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:
Divide and conquer的做法是把数组分成左右两边,然后:
If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle.
动态规划,注意这里必须要有至少一个元素。因此条件就是对于A[i],要么结果里有,要么没有。
public class Solution {
public int maxSubArray(int[] A) {
int[] x = new int[A.length];
x[0] = A[0];
int max = x[0];
for(int i = 1; i < A.length; i++){
x[i] = Math.max(x[i - 1] + A[i], A[i]);
max = Math.max(x[i], max);
}
return max;
}
}
Divide and conquer的做法是把数组分成左右两边,然后:
1.找左边的max subarray
2.找右边的max subarray
3.找包含中间元素的max subarray
对于1和2,用递归就行了。需要写一个函数来找3
public int maxThroughMid(int[] arr, int low, int mid, int high){
if(low == high)
return arr[low];
int leftMax = Integer.MIN_VALUE;
int sum = 0;
//find the max subarray on the left of the mid
for(int i = mid; i >= low; i--){
sum += arr[i];
leftMax = maxOfTwo(sum, leftMax);
}
//the max on the right
sum = 0;
int rightMax = Integer.MIN_VALUE;
for(int i = mid + 1; i <= high; i++){
sum += arr[i];
rightMax = maxOfTwo(sum, rightMax);
}
return leftMax + rightMax;
}
代码就是这样:
public class Solution {
public int maxSubArray(int[] A) {
return maxSubArrayRecur(A, 0, A.length - 1);
}
public int maxSubArrayRecur(int[] arr, int low, int high){
if(low == high){
return arr[low];
}
int mid = (low + high) / 2;
return maxOfThree(maxSubArrayRecur(arr, low, mid), maxSubArrayRecur(arr, low + 1, high), maxThroughMid(arr,low, mid, high));
}
public int maxOfThree(int a, int b, int c){
return maxOfTwo(maxOfTwo(a, b), c);
}
public int maxOfTwo(int a, int b){
if(a >= b)
return a;
else
return b;
}
//calculate the max subarray contanning the element arr[mid]
public int maxThroughMid(int[] arr, int low, int mid, int high){
if(low == high)
return arr[low];
int leftMax = Integer.MIN_VALUE;
int sum = 0;
//find the max subarray on the left of the mid
for(int i = mid; i >= low; i--){
sum += arr[i];
leftMax = maxOfTwo(sum, leftMax);
}
//the max on the right
sum = 0;
int rightMax = Integer.MIN_VALUE;
for(int i = mid + 1; i <= high; i++){
sum += arr[i];
rightMax = maxOfTwo(sum, rightMax);
}
return leftMax + rightMax;
}
}
但是online judge通不过,总是超时,先不管了。