一、穷举法
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 = 0;
int maxVal = arr[0];
int sum = 0;
for(int i = 0; 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;
}