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
.
More practice:
If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle.
解题思路:
1. 首先是简单的dp。
2. 对于分治,考虑将数组分为左右两段,则最大连续子序列和可能在左半段,也可能在右半段,还可能跨界。三种情况求最大就可以了。
class Solution { public: int dpSolution(int *a, int n) { if(n == 0) return 0; int *dp = new int[n + 1]; dp[0] = a[0]; int m = dp[0]; for(int i = 1;i < n;i++) { if(dp[i - 1] > 0) dp[i] = dp[i - 1] + a[i]; else dp[i] = a[i]; m = max(dp[i], m); } return m; } int *data; int divideConquerSolution(int *a, int n) { if(n == 0) return 0; data = a; return dcs(0, n); } int dcs(int a, int b) { if(b - a == 1) return data[a]; int mid = (a + b) / 2; int left = dcs(a, mid), right = dcs(mid, b); int rightSum = 0, leftSum = 0, rightMax = -(1 << 30), leftMax = -(1 << 30); for(int i = mid; i < b;i++) { rightSum += data[i]; rightMax = max(rightSum, rightMax); } for(int i = mid - 1; i >= a;i--) { leftSum += data[i]; leftMax = max(leftSum, leftMax); } return max(max(left, right), leftMax + rightMax); } int maxSubArray(int A[], int n) { // IMPORTANT: Please reset any member data you declared, as // the same Solution instance will be reused for each test case. // return dpSolution(A, n); return divideConquerSolution(A, n); } };