int MaxSubsequence(int *arr, int arrLen) { int maxSoFar = 0; int max = 0; for(int i = 0; i < arrLen; i++) { for(int j = i; j < arrLen; j++) { max = 0; for(int k = i; k <= j; k++) { max += arr[k]; } if(max > maxSoFar) maxSoFar = max; } } return maxSoFar; }上述穷举可以进一步优化,第三个for循环可以省略
int MaxSubsequence(int *arr, int arrLen) { int maxSoFar = 0; int max = 0; for(int i = 0; i < arrLen; i++) { max = 0; for(int j = i; j < arrLen; j++) { max += arr[j]; if(max > maxSoFar) maxSoFar = max; } } return maxSoFar; }
最大子序列可能出现在左部分,右部分和跨越左右部分。
int MaxSubsequence(int *arr, int left, int right) { if(left == right) if(arr[left] > 0) return arr[left]; else return 0; int leftMax = 0; int rightMax = 0; int center = (left + right) / 2; leftMax = MaxSubsequence(arr, left, center); rightMax = MaxSubsequence(arr, center+1, right); int max = 0; int leftBorder = 0; for(int i = center; i >= left; i--) { max += arr[i]; if(max > leftBorder) leftBorder = max; } max = 0; int rightBorder = 0; for(int i = center+1; i <= right; i++) { max += arr[i]; if(max > rightBorder) rightBorder = max; } return max3(leftMax, rightMax, leftBorder + rightBorder); }
三、线性法
int MaxSubsequence(int *arr, int arrLen) { int maxSoFar = 0; int max = 0; for(int i = 0; i < arrLen; i++) { max += arr[i]; if(max > maxSoFar) maxSoFar = max; else if(max < 0) max = 0; } return maxSoFar; }
考虑特殊情况,若数组中元素全部为负数,则上述解法得到的最大和为0,这不符合实际要求,应该为最大的负数。
例如:{-2,-4,-1,-8,-3,-5,-12,-34,-7}, 最大连续子序列值应该为-1。
解决办法:只需要在遍历的时候记住序列的最大值即可。
int SubSeq(int *arr, int len) { int maxSoFar = arr[0]; int maxVal = arr[0]; int sum = 0; for(int i = 1; i < len; i++) { sum += arr[i]; if(sum > maxSoFar) maxSoFar = sum; else if (sum < 0) sum = 0; if(maxVal < arr[i]) maxVal = arr[i]; } return maxVal > maxSoFar ? maxVal : maxSoFar; }