最大子序和问题:给定整数A1,A2,.....An(可能有负数),求A1 +A2+A3+......+An的最大值(规定:如果所有整数均为负数,则最大子序和为0)
例:
输入-2, 11, -4, 13, -5, -2时,答案为20(从A2到A4)。
下面给出四种不同复杂度的算法,进行比较分析
O(n3)的算法(穷举所有可能)
<span style="font-size:18px;">public static int maxSubsequenceSum(int[] nums) {
int ThisSum = 0;
int MaxSum = 0;
for (int i = 0; i < nums.length; i++) {
for (int j = i; j < nums.length; j++) {
ThisSum = 0;
for (int k = i; k < j; k++) {
ThisSum += nums[k];
}
if (ThisSum > MaxSum)
MaxSum = ThisSum;
}
}
return MaxSum;
}
}</span>
<span style="font-size:18px;">O(n2)的算法(去掉一次for循环)
</span><pre name="code" class="java"><span style="font-size:18px;">public static int maxSubsequenceSum(int[] nums) {
int ThisSum = 0;
int MaxSum = 0;
for (int i = 0; i < nums.length; i++) {
ThisSum = 0;
for (int j = i; j < nums.length; j++) {
ThisSum += nums[j];
if (ThisSum > MaxSum)
MaxSum = ThisSum;
}
}
return MaxSum;
}
}</span>
O(nlogn)的算法(利用分治的策略,代码比较复杂)
<span style="font-size:18px;">public static int maxSubSum(int[] nums, int Left, int Right) {
int MaxLeftSum, MaxRightSum;
if (Left == Right){
if (nums[0] > 0)
return nums[0];
else
return 0;
}
int Center = (Left + Right) / 2;
MaxLeftSum = maxSubSum(nums, Left, Center);
MaxRightSum = maxSubSum(nums, Center + 1, Right);
int MaxLeftBorderSum = 0, LeftBorderSum = 0;
for (int i = Center; i >= Left; i--) {
LeftBorderSum += nums[i];
if (LeftBorderSum > MaxLeftBorderSum)
MaxLeftBorderSum = LeftBorderSum;
}
int MaxRightBorderSum = 0, RightBorderSum = 0;
for (int i = Center + 1; i < Right; i++) {
RightBorderSum += nums[i];
if (RightBorderSum > MaxRightBorderSum)
MaxRightBorderSum = RightBorderSum;
}
int max = MaxLeftSum;
max = (max < MaxLeftSum ? MaxLeftSum : max);
max = (max < (MaxLeftBorderSum + MaxRightBorderSum) ? (MaxLeftBorderSum + MaxRightBorderSum) : max);
return max;
}</span>
O(n)的算法(最为巧妙地算法)
<span style="font-size:18px;">public static int maxSum(int[] nums) {
int thisSum = 0;
int maxSum = 0;
for (int i = 0; i <nums.length; i++){
thisSum += nums[i];
if (maxSum < thisSum){
maxSum = thisSum;
}
if (thisSum < 0){
thisSum = 0;
}
}
return maxSum;
}
</span>