Description
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.
Solving
-
Using the dynamic programming, which is an O(n) solution.
Using an n-length array named dp to put the maximum sum until the i position.
First
result = nums[0]
,dp[0] = nums[0]
When
dp[i - 1] <= 0
,dp[i] = nums[i]
.When
dp[i - 1] > 0
,dp[i] = dp[i - 1] + nums[i]
.Every step should compare
result
anddp[i]
, andresult
will be the bigger one.public int maxSubArray(int[] nums) { if (nums.length == 0) return 0; int[] dp = new int[nums.length]; dp[0] = nums[0]; int res = nums[0]; for (int i = 1; i < nums.length; i ++) { dp[i] = nums[i] + (dp[i - 1] > 0? dp[i - 1]: 0); res = Math.max(dp[i], res); } return res; }
-
Using the divide and conquer approach, which is more subtle.
There are three condition:
- The result will be the left slice of this array.
- The result will be the mid slice of this array.
- The result will be the right slice of this array.
public int maxSubArray(int[] nums) { return maxSubSum(nums, 0, nums.length - 1); } private int maxSubSum(int[] nums, int left, int right) { if (left > right) return Integer.MIN_VALUE; int mid = left + (right - left) / 2; int leftSum = maxSubSum(nums, left, mid - 1); int rightSum = maxSubSum(nums, mid + 1, right); int midLeftSum = 0, midRightSum = 0; for (int i = mid - 1, sum = 0; i >= left; i --) { sum += nums[i]; midLeftSum = Math.max(midLeftSum, sum); } for (int i = mid + 1, sum = 0; i <= right; i ++) { sum += nums[i]; midRightSum = Math.max(midRightSum, sum); } return Math.max(nums[mid] + midLeftSum + midRightSum, Math.max(leftSum, rightSum)); }