|
| 1 | +# [Maximum Subarray][title] |
| 2 | + |
| 3 | +## Description |
| 4 | + |
| 5 | +Find the contiguous subarray within an array (containing at least one number) which has the largest sum. |
| 6 | + |
| 7 | +For example, given the array `[-2,1,-3,4,-1,2,1,-5,4]`, |
| 8 | +the contiguous subarray `[4,-1,2,1]` has the largest sum = `6`. |
| 9 | + |
| 10 | +**More practice:** |
| 11 | + |
| 12 | +If you have figured out the O(*n*) solution, try coding another solution using the divide and conquer approach, which is more subtle. |
| 13 | + |
| 14 | +**Tags:** Array, Dynamic Programming, Divide and Conquer |
| 15 | + |
| 16 | + |
| 17 | +## 思路0 |
| 18 | + |
| 19 | +题意是求数组中子数组的最大和,这种最优问题一般第一时间想到的就是动态规划,我们可以这样想,当部分序列和大于零的话就一直加下一个元素即可,并和当前最大值进行比较,如果出现部分序列小于零的情况,那肯定就是从当前元素算起。其转移方程就是`dp[i] = nums[i] + (dp[i - 1] > 0 ? dp[i - 1] : 0);`,由于我们不需要保留dp状态,故可以优化空间复杂度为1,即`dp = nums[i] + (dp > 0 ? dp : 0);`。 |
| 20 | + |
| 21 | +``` java |
| 22 | +public class Solution { |
| 23 | + public int maxSubArray(int[] nums) { |
| 24 | + int len = nums.length, dp = nums[0], max = dp; |
| 25 | + for (int i = 1; i < len; ++i) { |
| 26 | + dp = nums[i] + (dp > 0 ? dp : 0); |
| 27 | + if (dp > max) max = dp; |
| 28 | + } |
| 29 | + return max; |
| 30 | + } |
| 31 | +} |
| 32 | +``` |
| 33 | + |
| 34 | +## 思路1 |
| 35 | + |
| 36 | +题目也给了我们另一种思路,就是分治,所谓分治就是把问题分割成更小的,最后再合并即可,我们把`nums`一分为二先,那么就有两种情况,一种最大序列包括中间的值,一种就是不包括,也就是在左边或者右边;当最大序列在中间的时候那我们就把它两侧的最大和算出即可;当在两侧的话就继续分治即可。 |
| 37 | + |
| 38 | +``` java |
| 39 | +public class Solution { |
| 40 | + public int maxSubArray(int[] nums) { |
| 41 | + return helper(nums, 0, nums.length - 1); |
| 42 | + } |
| 43 | + |
| 44 | + private int helper(int[] nums, int left, int right) { |
| 45 | + if (left >= right) return nums[left]; |
| 46 | + int mid = (left + right) >> 1; |
| 47 | + int leftAns = helper(nums, left, mid); |
| 48 | + int rightAns = helper(nums, mid + 1, right); |
| 49 | + int leftMax = nums[mid], rightMax = nums[mid + 1]; |
| 50 | + int temp = 0; |
| 51 | + for (int i = mid; i >= left; --i) { |
| 52 | + temp += nums[i]; |
| 53 | + if (temp > leftMax) leftMax = temp; |
| 54 | + } |
| 55 | + temp = 0; |
| 56 | + for (int i = mid + 1; i <= right; ++i) { |
| 57 | + temp += nums[i]; |
| 58 | + if (temp > rightMax) rightMax = temp; |
| 59 | + } |
| 60 | + return Math.max(Math.max(leftAns, rightAns), leftMax + rightMax); |
| 61 | + } |
| 62 | +} |
| 63 | +``` |
| 64 | + |
| 65 | + |
| 66 | +## 结语 |
| 67 | + |
| 68 | +如果你同我一样热爱数据结构、算法、LeetCode,可以关注我GitHub上的LeetCode题解:[awesome-java-leetcode][ajl] |
| 69 | + |
| 70 | + |
| 71 | + |
| 72 | +[title]: https://leetcode.com/problems/maximum-subarray |
| 73 | +[ajl]: https://github.com/Blankj/awesome-java-leetcode |
0 commit comments