Given an integer array nums
, find the contiguous subarray (containing at least one number) which has the largest sum and return its sum.
Example:
Input: [-2,1,-3,4,-1,2,1,-5,4], Output: 6 Explanation: [4,-1,2,1] has the largest sum = 6.
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.
定义两个变量maxGlobal和maxLocal,其中maxGlobal保存最终要返回的结果,即最大的子数组之和,maxLocal和maxGlobal初始值为nums[0],每遍历一个数字num,比较maxLocal + num和num中的较大值存入maxLocal,然后再把maxGlobal和maxLocal中的较大值存入maxGlobal,以此类推直到遍历完整个数组,可得到最大子数组的值存在maxGlobal中
class Solution {
public int maxSubArray(int[] nums) {
int maxLocal = nums[0];
int maxGlobal = nums[0];
for (int i = 1; i < nums.length; i++) {
maxLocal = Math.max(nums[i], maxLocal + nums[i]);
maxGlobal = Math.max(maxGlobal, maxLocal);
}
return maxGlobal;
}
}
题目还要求我们用分治法Divide and Conquer Approach来解,这个分治法的思想就类似于二分搜索法,我们需要把数组一分为二,分别找出左边和右边的最大子数组之和,然后还要从中间开始向左右分别扫描,求出的最大值分别和左右两边得出的最大值相比较取最大的那一个
public class Solution {
public int maxSubArray(int[] nums) {
if (nums.length == 0) return 0;
return helper(nums, 0, nums.length - 1);
}
public int helper(int[] nums, int left, int right) {
if (left >= right) return nums[left];
int mid = left + (right - left) / 2;
int lmax = helper(nums, left, mid - 1);
int rmax = helper(nums, mid + 1, right);
int mmax = nums[mid], t = mmax;
for (int i = mid - 1; i >= left; --i) {
t += nums[i];
mmax = Math.max(mmax, t);
}
t = mmax;
for (int i = mid + 1; i <= right; ++i) {
t += nums[i];
mmax = Math.max(mmax, t);
}
return Math.max(mmax, Math.max(lmax, rmax));
}
}