Maximum Subarray
Total Accepted: 28381 Total Submissions: 83696 My Submissions
Find the contiguous subarray within an array (containing at least one number) which has the largest sum.For example, given the array [−2,1,−3,4,−1,2,1,−5,4],
the contiguous subarray [4,−1,2,1] has the largest sum = 6.
設數組爲A[n], dp[n-1]是前n-1個數的最大子序列,那麼dp[n]=dp[n-1]>0?dp[n-1]+A[n]:A[n].用這個算法從最左邊到最右邊掃描連續子序列的和.
那麼最大的子序列怎麼求。每次都用之求maxSum=max{dp[n],maxSum}保存最大的子序列。
對於元素n=0, sum=A[0],最大序列和爲maxSum=A[0] 顯然成立,
根據循環不變性.對於n
1、設dp[n-1]當前某段連續子序列的和,我們假設爲A[n-1]=dp[n-1],即假設A[n-1]爲該段前面的子序列和.如果A[n-1]>=0,那麼A[n-1]+A[n]自然是{A[n-1],A[n]}這個序列的最大值。意味着這段連續子序列仍然增加,並把A[n]包含進這段連續子序列,這段連續子序列的值相應也增加了.
2、如果A[n-1]<0,那麼A[n]就是這個連續子序列的最大值。意味重新開始了一段新的連續子序列。
3、假設maxSum爲之前的最大連續子序列和,使用maxSum=max(A[n],maxSum)可以求前一段連續子序列和當前子序列的最大值,這個函數保證了在n時,maxSum仍然是A[0].....A[n]的最大連續子序列和.
在n結束時仍然滿足循環不變性,算法證畢.
class Solution {
public:
int maxSubArray(int A[], int n) {
int sum=A[0],maxSum=A[0];
for(int i=1;i<n;i++)
{
if(sum<0) sum=0;
sum+=A[i];
maxSum=max(sum,maxSum);
}
return maxSum;
}
};