最大子序列和问题的求解
第一个算法如下,用穷举的方法求出所有的子序列和,返回最大值。
public static int maxSubSumBad(int[] a){
int maxSum=0;
for(int i=0;i<a.length;i++){
int thisSum=0;
for(int j=i;j<a.length;j++){
thisSum+=a[j];
if(thisSum>maxSum)
maxSum=thisSum;
}
}
return maxSum;
}
该算法的时间复杂度为O(N^2),而解决该问题还有更好的办法。可以采用“分治”策略,“分”将问题分为两个大致相等的子问题,然后递归地对其分解;“治”将两个子问题的解附加到一起,最后得到整个问题的解。
在本问题中,最大子序列和可能出现在3处,或整个出现在输入数据的左半部分,或整个出现在输入数据的右半部,或位于输入数据的中部。前两种情况可以递归求解。第三种情况可以求出前半部分的最大和以及后半部分的最大和从而得到。
实现如下:
public static int maxSubSum(int[] a){
return maxSumRec(a,0,a.length-1);
}
private static int maxSumRec(int[] a,int left,int right){
if(left==right){
if(a[left]>0)
return a[left];
else
return 0;
}
int center=(left+right)/2;
int maxLeftSum=maxSumRec(a,left,center);
int maxRightSum=maxSumRec(a,center+1,right);
int maxLeftBorderSum=0,leftBorderSum=0;
for(int i=center;i>=left;i--){
leftBorderSum+=a[i];
if(leftBorderSum>maxLeftBorderSum)
maxLeftBorderSum=leftBorderSum;
}
int maxRightBorderSum=0,rightBorderSum=0;
for(int i=center+1;i<=right;i++){
rightBorderSum+=a[i];
if(rightBorderSum>maxRightBorderSum)
maxRightBorderSum=rightBorderSum;
}
return maxInThree(maxLeftSum,maxRightSum,maxLeftBorderSum+maxRightBorderSum);
}
public static int maxInThree(int first,int second,int third){
int max=0;
if(first>=second)
max=first;
else
max=second;
if(max<third)
max=third;
return max;
}
该方法的时间复杂度为O(NlogN)。而通过思考可以得到结论:如果a[i]是负的,那么它不可能是最有序列的起点,因为任何以a[i]为起点的序列都可以通过以a[i+1]作为起点得到改进。类似地,任何负的子序列不可能是最优子序列的前缀。可以写出如下方法:
public static int maxSubSum2(int[] a){
int maxSum=0,thisSum=0;
for(int i=0;i<a.length;i++){
thisSum+=a[i];
if(maxSum<thisSum)
maxSum=thisSum;
else if(thisSum<0)
thisSum=0;
}
return maxSum;
}
该算法的时间复杂度为O(N),它只对数据进行一次扫描。在任意时刻,算法都能对它已经读入的数据给出正确答案。具有这种特性的算法叫做
联机算法。
分享到:
相关推荐
计算机算法分析与设计最大连续子序列是计算机科学领域中的一种经典算法问题,具有很高的实践价值和理论价值。解决该问题需要使用动态规划法,读取输入数据,记录最大和和历史最大的和,并输出最大和、最大连续子序列...
实验5.4的主题是求解最大子序列和以及最大子矩阵的问题,这涉及到经典的动态规划算法。最大子序列和问题是一维数组中最长的连续子序列,使得子序列的和最大。最大子矩阵和问题是在二维矩阵中找到一个矩形区域,其...
最大公共子序列(Longest Common Subsequence, LCS)算法是一种经典的计算机科学问题,主要应用于比较和分析两个或多个序列的相似性。在本场景中,我们关注的是C++实现的全过程输出版本,这意味着代码不仅会找到两个...
在这个“算法分析实验_最大子段和问题代码”中,我们关注的是一个经典的算法问题——寻找数组中的最大子段和。这是一个重要的计算机科学问题,它涉及到动态规划和数组处理的基本概念。在这里,开发者使用C#编程语言...
在IT领域,特别是算法设计和分析中,"连续子序列最大和与乘积问题"是一个经典的话题。这类问题经常出现在数据结构和算法的面试中,也是优化和解决复杂计算问题的关键。本文将深入探讨这个问题,并结合提供的Java源码...
最长公共子序列(Longest Common Subsequence,简称LCS)问题属于计算机科学领域中的一个重要问题,尤其是在算法设计与分析方面。此问题的核心在于寻找两个序列的最长公共子序列。其中,“子序列”指的是在原序列中...
《算法导论》是计算机科学领域的一门重要课程,它涵盖了广泛的算法设计和分析技术。在本实验中,我们关注的是“最长递增子序列”(Longest Increasing Subsequence, LIS)这一经典问题,它是算法课程中的一个核心...
算法设计与分析 最大公共子序列问题 。
动态规划的一个计算两个序列的最长公共子序列的方法如下: 以两个序列 X、Y 为例子: 设有二维数组 f[i,j] 表示 X 的 i 位和 Y 的 j 位之前的最长公共子序列的长度,则有: f[1][1] = same(1,1); f[i,j] = max{f[i-1...
该算法遍历整个序列,保持两个变量:当前子序列的和(current_sum)和最大子序列和(max_sum)。如果当前元素大于current_sum加上当前元素,那么更新current_sum;否则,令current_sum等于当前元素。每次比较后,max...
最长公共子序列(Longest Common Subsequence,LCS)算法是一种经典的计算机科学问题,主要应用于比较和分析两个或多个序列的相似性。在文本编辑、生物信息学、数据挖掘等领域有着广泛的应用。LCS的基本思想是寻找两...
算法分析与设计最近对问题最大子段和(分治法最大子段和动态规划) 最近对问题最大子段和(分治法)是算法设计与分析中一个重要的知识点,它是指在一组点集中找到最近对点的距离。该问题可以通过分治法和动态规划来...
通过以上分析,我们可以看到最大上升子序列和问题是一个典型的动态规划应用实例,不仅能够锻炼学生对动态规划的理解与应用能力,同时也涉及到数组操作、条件判断等基本编程技巧,非常适合初学者进行练习。
2. 最长公共子序列(LCS):找到两个序列不相交部分的最大长度,常用于比较文本相似度。 3. 矩阵链乘法:优化多矩阵相乘的计算顺序,减少运算次数。 五、贪心算法与回溯法 1. 贪心算法:每一步都采取当前看来最优的...
最大公共子序列(Longest Common Subsequence,LCS)是计算机科学中的一种经典问题,主要应用于比较和分析两个序列的相似性。在这个问题中,我们寻找两个给定序列的最长子序列,这个子序列并不需要在原序列中连续...
### C++实现最长公共子序列算法详解 在深入解析给定代码之前,我们先来了解一下“最长公共子序列”(Longest Common Subsequence,简称LCS)的基本概念及其在计算机科学中的应用。LCS问题是一种典型的动态规划问题...
C源程序——两个序列的最大公共子序列#include #include #define MAX 100 char x[MAX+1],y[MAX+1]; int b[MAX+1][MAX+1],c[MAX+1][MAX+1],m,n; static void Init_XY(void); static void LCS_Length(void); static...
实验的目标是锻炼学生通过设计、实现和分析算法解决问题的能力,这一目标在解决最长递增子序列问题时体现得尤为明显。动态规划作为一种算法思想,在此类问题的解决中具有独特的优越性。其核心在于将复杂问题分解为一...
例如,在序列 `(1, 7, 3, 5, 9, 4, 8)` 中,`(1, 3, 5, 8)` 是一个长度为 4 的单调递增子序列,也是该序列中最长的单调递增子序列之一。 问题的目标是找到给定序列中最长的单调递增子序列,并输出其长度。 #### ...