您的位置:首页 > 其它

最大子序列问题

2007-12-09 20:27 337 查看
问题描述:给定整数A1,A2,...,AN(可能为负数),求(Ai+...Aj)的最大值(为了方便起见,如果所有整数均为负数,则最大子序列和为0)。
1.首先给出了一个递归的算法 复杂度为O(Nlog(N)),这个方法采用一种“分治”(divide-and-conquer)策略。在我们的例子中,最大子序列和可能出现在三处。或者整个出现在输入数据的左半部,或者整个出现右半部,或者跨越输入数据的中部从而占据左右两个半部分。前两种情况递归求解。第三种情况的最大和可以通过求出前半部分的最大和(包含前半部分的最后一个元素)以及后半部分的最大和(包含后半部分的第一个元素)而得到,然后将这两个和加在一起,求出三个值的最大值:
int maxSumRec(const vector<int>& a, int left, int right)
...{
if(left==right) //base case
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; j++)
...{
rightBorderSum += a[j];
if(rightBorderSum > maxRightBorderSum )
maxRightBorderSum = rightBorderSum;
}

return std::max(maxLeftSum, std::max(maxRightSum,maxLeftBorderSum+maxRightBorderSum));
}
2、第二个算法的复杂度为O(N)
int maxSubSum(const vector<int>& a)
...{
int maxSum = 0;
int thisSum = 0;
for(int i = 0; i < a.size(); i++)
...{
thisSum += a[i];
if(thisSum > maxSum)
maxSum = thisSum;
else if( thisSum < 0)
thisSum = 0;
}
return maxSum;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: