Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit c112103

Browse files
Merge pull request SharingSource#51 from SharingSource/ac_oier
✨feat: Add 剑指 Offer 42
2 parents ae61b88 + 6d86113 commit c112103

File tree

3 files changed

+177
-1
lines changed

3 files changed

+177
-1
lines changed

‎Index/线性 DP.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,6 @@
1111
| [403. 青蛙过河](https://leetcode-cn.com/problems/frog-jump/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/frog-jump/solution/gong-shui-san-xie-yi-ti-duo-jie-jiang-di-74fw/) | 困难 | 🤩🤩🤩 |
1212
| [1751. 最多可以参加的会议数目 II](https://leetcode-cn.com/problems/maximum-number-of-events-that-can-be-attended-ii/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/maximum-number-of-events-that-can-be-attended-ii/solution/po-su-dp-er-fen-dp-jie-fa-by-ac_oier-88du/) | 困难 | 🤩🤩🤩 |
1313
| [1787. 使所有区间的异或结果为零](https://leetcode-cn.com/problems/make-the-xor-of-all-segments-equal-to-zero/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/make-the-xor-of-all-segments-equal-to-zero/solution/gong-shui-san-xie-chou-xiang-cheng-er-we-ww79/) | 困难 | 🤩🤩🤩🤩 |
14+
| [剑指 Offer 42. 连续子数组的最大和](https://leetcode-cn.com/problems/lian-xu-zi-shu-zu-de-zui-da-he-lcof/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/lian-xu-zi-shu-zu-de-zui-da-he-lcof/solution/gong-shui-san-xie-jian-dan-xian-xing-dp-mqk5v/) | 简单 | 🤩🤩🤩🤩🤩 |
1415
| [LCP 07. 传递信息](https://leetcode-cn.com/problems/chuan-di-xin-xi/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/chuan-di-xin-xi/solution/gong-shui-san-xie-tu-lun-sou-suo-yu-dong-cyxo/) | 简单 | 🤩🤩🤩🤩 |
1516

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
### 题目描述
2+
3+
这是 LeetCode 上的 **[剑指 Offer 42. 连续子数组的最大和](https://leetcode-cn.com/problems/lian-xu-zi-shu-zu-de-zui-da-he-lcof/solution/gong-shui-san-xie-jian-dan-xian-xing-dp-mqk5v/)** ,难度为 **简单**
4+
5+
Tag : 「线性 DP」
6+
7+
8+
9+
10+
输入一个整型数组,数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值。
11+
12+
要求时间复杂度为$O(n)$。
13+
14+
15+
示例1:
16+
```
17+
输入: nums = [-2,1,-3,4,-1,2,1,-5,4]
18+
19+
输出: 6
20+
21+
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
22+
```
23+
24+
提示:
25+
* 1 <= arr.length <= 10ドル^5$
26+
* -100 <= arr[i] <= 100
27+
28+
---
29+
30+
### 动态规划
31+
32+
这是一道简单线性 DP 题。
33+
34+
定义 $f[i]$ 为考虑以 $nums[i]$ 为结尾的子数组的最大值。
35+
36+
不失一般性的考虑 $f[i]$ 如何转移。
37+
38+
显然对于 $nums[i]$ 而言,以它为结尾的子数组分两种情况:
39+
40+
* $num[i]$ 自身作为独立子数组:$f[i] = nums[i]$ ;
41+
* $num[i]$ 与之前的数值组成子数组,由于是子数组,其只能接在 $nums[i - 1],ドル即有:$f[i] = f[i - 1] + nums[i]$。
42+
43+
最终 $f[i]$ 为上述两种情况取 $\max$ 即可:
44+
45+
$$
46+
f[i] = \max(nums[i], f[i - 1] + nums[i])
47+
$$
48+
49+
代码:
50+
```Java
51+
class Solution {
52+
public int maxSubArray(int[] nums) {
53+
int n = nums.length;
54+
int[] f = new int[n];
55+
f[0] = nums[0];
56+
int ans = f[0];
57+
for (int i = 1; i < n; i++) {
58+
f[i] = Math.max(nums[i], f[i - 1] + nums[i]);
59+
ans = Math.max(ans, f[i]);
60+
}
61+
return ans;
62+
}
63+
}
64+
```
65+
* 时间复杂度:$O(n)$
66+
* 空间复杂度:$O(n)$
67+
68+
---
69+
70+
71+
### 空间优化
72+
73+
观察状态转移方程,我们发现 $f[i]$ 明确值依赖于 $f[i - 1]$。
74+
75+
因此我们可以使用「有限变量」或者「滚动数组」的方式,将空间优化至 $O(1)$。
76+
77+
代码:
78+
```Java
79+
class Solution {
80+
public int maxSubArray(int[] nums) {
81+
int n = nums.length;
82+
int max = nums[0], ans = max;
83+
for (int i = 1; i < n; i++) {
84+
max = Math.max(nums[i], max + nums[i]);
85+
ans = Math.max(ans, max);
86+
}
87+
return ans;
88+
}
89+
}
90+
```
91+
```Java
92+
class Solution {
93+
public int maxSubArray(int[] nums) {
94+
int n = nums.length;
95+
int[] f = new int[2];
96+
f[0] = nums[0];
97+
int ans = f[0];
98+
for (int i = 1; i < n; i++) {
99+
int a = i & 1, b = (i - 1) & 1;
100+
f[a] = Math.max(nums[i], f[b] + nums[i]);
101+
ans = Math.max(ans, f[a]);
102+
}
103+
return ans;
104+
}
105+
}
106+
```
107+
* 时间复杂度:$O(n)$
108+
* 空间复杂度:$O(1)$
109+
110+
111+
---
112+
113+
### 拓展
114+
115+
一个有意思的拓展是,将 **加法** 替换成 **乘法**
116+
117+
题目变成 [152. 乘积最大子数组(中等)](https://leetcode-cn.com/problems/maximum-product-subarray/)
118+
119+
又该如何考虑呢?
120+
121+
一个朴素的想法,仍然是考虑定义 $f[i]$ 代表以 $nums[i]$ 为结尾的最大值,但存在「负负得正」取得最大值的情况,光维护一个前缀最大值显然是不够的,我们可以多引入一维 $g[i]$ 作为前缀最小值。
122+
123+
其余分析与本题同理。
124+
125+
代码:
126+
```Java
127+
class Solution {
128+
public int maxProduct(int[] nums) {
129+
int n = nums.length;
130+
int[] g = new int[n + 1]; // 考虑前 i 个,结果最小值
131+
int[] f = new int[n + 1]; // 考虑前 i 个,结果最大值
132+
g[0] = 1;
133+
f[0] = 1;
134+
int ans = nums[0];
135+
for (int i = 1; i <= n; i++) {
136+
int x = nums[i - 1];
137+
g[i] = Math.min(x, Math.min(g[i - 1] * x, f[i - 1] * x));
138+
f[i] = Math.max(x, Math.max(g[i - 1] * x, f[i - 1] * x));
139+
ans = Math.max(ans, f[i]);
140+
}
141+
return ans;
142+
}
143+
}
144+
```
145+
```Java
146+
class Solution {
147+
public int maxProduct(int[] nums) {
148+
int n = nums.length;
149+
int min = 1, max = 1;
150+
int ans = nums[0];
151+
for (int i = 1; i <= n; i++) {
152+
int x = nums[i - 1];
153+
int nmin = Math.min(x, Math.min(min * x, max * x));
154+
int nmax = Math.max(x, Math.max(min * x, max * x));
155+
min = nmin;
156+
max = nmax;
157+
ans = Math.max(ans, max);
158+
}
159+
return ans;
160+
}
161+
}
162+
```
163+
164+
---
165+
166+
### 最后
167+
168+
这是我们「刷穿 LeetCode」系列文章的第 `No.剑指 Offer 42` 篇,系列开始于 2021年01月01日,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。
169+
170+
在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。
171+
172+
为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode
173+
174+
在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。
175+

‎LeetCode/剑指 Offer/剑指 Offer 53 - I. 在排序数组中查找数字 I(简单).md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
### 题目描述
22

3-
这是 LeetCode 上的 **[剑指 Offer 53 - I. 在排序数组中查找数字 I](https://leetcode-cn.com/problems/zai-pai-xu-shu-zu-zhong-cha-zhao-shu-zi-lcof/solution/gong-shui-san-xie-liang-chong-er-fen-ton-3epx/)** ,难度为 **中等**
3+
这是 LeetCode 上的 **[剑指 Offer 53 - I. 在排序数组中查找数字 I](https://leetcode-cn.com/problems/zai-pai-xu-shu-zu-zhong-cha-zhao-shu-zi-lcof/solution/gong-shui-san-xie-liang-chong-er-fen-ton-3epx/)** ,难度为 **简单**
44

55
Tag : 「二分」
66

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /