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.
DP state: dp[i]指以当前数结尾的subarray的最大值 function: dp[i] =
dp[i - 1] + nums[i] (dp[i - 1] > 0)
nums[i] (dp[i - 1] <= 0)
init: dp[0] = nums[0] answer: max(dp[i])
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public int maxSubArray (int [] nums) {
if (nums == null || nums.length == 0 )
return 0 ;
int [] dp = new int [2 ];
dp[0 ] = nums[0 ];
int ans = nums[0 ];
for (int i = 1 ; i < nums.length; i++) {
if (dp[(i - 1 ) % 2 ] > 0 ) {
dp[i % 2 ] = dp[(i - 1 ) % 2 ] + nums[i];
} else {
dp[i % 2 ] = nums[i];
}
ans = Math.max(ans, dp[i % 2 ]);
}
return ans;
}
prefix sum array subarray的问题大部分都可以用prefix sum array来解 求得prefix sum array, 题目就转变成了 121. Best Time to Buy and Sell Stock
. 就是找后面的数和前面的数的差的最大值。 按题目中的示例来说,prefix sum array就是 [-2, -1, -4, 0, -1, 1, 2, -3, 1]. 最大值是prefix[6] - prefix[2] = 6
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public int maxSubArray(int [] nums) {
if (nums == null || nums.length == 0 )
return 0 ;
int [] prefix = new int [nums.length ];
prefix[0 ] = nums[0 ];
for (int i = 1 ; i < nums.length ; i++) {
prefix[i] = prefix[i - 1 ] + nums[i];
}
int min = 0 ;
int ans = prefix[0 ];
for (int i = 0 ; i < nums.length ; i++) {
ans = Math.max (ans, prefix[i] - min );
min = Math.min (min , prefix[i]);
}
return ans;
}
Kadane’s algorithm Ref: https://en.wikipedia.org/wiki/Maximum_subarray_problem
1
2
3
4
5
6
7
8
9
10
11
12
public int maxSubArray(int [] nums) {
if (nums == null || nums.length == 0 )
return Integer.MIN_VALUE;
int maxEndingHere = nums[0 ];
int maxSoFar = nums[0 ];
for (int i = 1 ; i < nums.length ; i++) {
maxEndingHere = Math.max (maxEndingHere + nums[i], nums[i]);
maxSoFar = Math.max (maxSoFar, maxEndingHere);
}
return maxSoFar;
}