Skip to content

Commit 04a7bd8

Browse files
committed
feat: add 053
1 parent e8066bc commit 04a7bd8

File tree

3 files changed

+124
-0
lines changed

3 files changed

+124
-0
lines changed

README.md

+2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
|28|[Implement strStr()][028]|Two Pointers, String|
1919
|35|[Search Insert Position][035]|String|
2020
|38|[Count and Say][038]|String|
21+
|53|[Maximum Subarray][053]|Array, Dynamic Programming, Divide and Conquer|
2122
|58|[Length of Last Word][058]|String|
2223

2324

@@ -55,4 +56,5 @@
5556
[028]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/028/README.md
5657
[035]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/035/README.md
5758
[038]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/038/README.md
59+
[053]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/053/README.md
5860
[058]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/058/README.md

note/053/README.md

+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
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
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package com.blankj.easy._053;
2+
3+
/**
4+
* <pre>
5+
* author: Blankj
6+
* blog : http://blankj.com
7+
* time : 2017/04/21
8+
* desc :
9+
* </pre>
10+
*/
11+
12+
public class Solution {
13+
public int maxSubArray(int[] nums) {
14+
int len = nums.length, dp = nums[0], max = dp;
15+
for (int i = 1; i < len; ++i) {
16+
dp = nums[i] + (dp > 0 ? dp : 0);
17+
if (dp > max) max = dp;
18+
}
19+
return max;
20+
}
21+
// public int maxSubArray(int[] nums) {
22+
// return helper(nums, 0, nums.length - 1);
23+
// }
24+
//
25+
// private int helper(int[] nums, int left, int right) {
26+
// if (left >= right) return nums[left];
27+
// int mid = (left + right) >> 1;
28+
// int leftAns = helper(nums, left, mid);
29+
// int rightAns = helper(nums, mid + 1, right);
30+
// int leftMax = nums[mid], rightMax = nums[mid + 1];
31+
// int temp = 0;
32+
// for (int i = mid; i >= left; --i) {
33+
// temp += nums[i];
34+
// if (temp > leftMax) leftMax = temp;
35+
// }
36+
// temp = 0;
37+
// for (int i = mid + 1; i <= right; ++i) {
38+
// temp += nums[i];
39+
// if (temp > rightMax) rightMax = temp;
40+
// }
41+
// return Math.max(Math.max(leftAns, rightAns), leftMax + rightMax);
42+
// }
43+
44+
public static void main(String[] args) {
45+
Solution solution = new Solution();
46+
int[] nums0 = new int[]{-2, 1, -3, 4, -1, 2, 1, -5, 4};
47+
System.out.println(solution.maxSubArray(nums0));
48+
}
49+
}

0 commit comments

Comments
 (0)