Description
Given an integer array nums, find the contiguous subarray (containing at least one number) which has the largest sum and return its sum.
Follow up:
If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle.
Example
Input: [-2,1,-3,4,-1,2,1,-5,4],
Output: 6
Explanation: [4,-1,2,1] has the largest sum = 6.
解题思路 O(n)
从头到尾过一遍就可以得到最优解,原理是如果到目前为止的sum小于0,那他一定不在子序列里面,从0开始计数
class Solution {
public int maxSubArray(int[] nums) {
if(nums.length == 0)
return 0;
int sum = nums[0];
int curr = 0;
int i;
for(i = 0; i < nums.length; i++){
curr += nums[i];
if(sum < curr)
sum = curr;
if(curr < 0)
curr = 0;
}
return sum;
}
}
分治法
对于一个数字串来说,将它对半分成两部分,那么他的最大序列和可能出现在左侧、右侧、或者中间
左侧和右侧可以通过递归计算,中间则直接求即可
class Solution {
public int findMax(int[] nums, int start, int end){
if(end - start == 0)
return nums[start];
int leftMax;
int rightMax;
int mid = (start + end) / 2;
int sum;
leftMax = findMax(nums, start, mid);
rightMax = findMax(nums, mid + 1, end);
int i;
int sum_r = Integer.MIN_VALUE;
int sum_l = Integer.MIN_VALUE;
int temp = 0;
for(i = mid; i <= end; i++){
temp += nums[i];
if(temp > sum_r)
sum_r = temp;
}
temp = 0;
for(i = mid - 1; i >= start; i--){
temp += nums[i];
if(temp > sum_l)
sum_l = temp;
}
if(sum_r < 0 && sum_r != Integer.MIN_VALUE)
sum = sum_l;
else if(sum_l < 0 && sum_l != Integer.MIN_VALUE)
sum = sum_r;
else
sum = sum_r + sum_l;
if(sum_r == Integer.MIN_VALUE){
if(sum_l == Integer.MIN_VALUE){
sum = Integer.MIN_VALUE;
}
else
sum = sum_l;
}
if(sum_l == Integer.MIN_VALUE){
if(sum_r == Integer.MIN_VALUE){
sum = Integer.MIN_VALUE;
}
else
sum = sum_r;
}
if(leftMax > rightMax && leftMax > sum){
return leftMax;
}
if(rightMax > leftMax && rightMax > sum){
return rightMax;
}
if(sum > leftMax && sum > rightMax){
return sum;
}
return rightMax > leftMax? rightMax: leftMax;
}
public int maxSubArray(int[] nums) {
return findMax(nums, 0, nums.length - 1);
}
}