Skip to content

Commit 4d07a0f

Browse files
committed
feat: add solutions to lcof problem: No.42
1 parent 4e3c726 commit 4d07a0f

File tree

7 files changed

+116
-90
lines changed

7 files changed

+116
-90
lines changed

lcof/面试题42. 连续子数组的最大和/README.md

Lines changed: 75 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,29 @@
2929

3030
## 解法
3131

32-
设 dp[i] 表示 `[0..i]` 中,以 `nums[i]` 结尾的最大子数组和,状态转移方程 `dp[i] = nums[i] + max(dp[i - 1], 0)`
32+
**方法一:动态规划**
3333

34-
由于 `dp[i]` 只与子问题 `dp[i-1]` 有关,故可以用一个变量 f 来表示。
34+
我们定义 $f[i]$ 表示以第 $i$ 个数结尾的「连续子数组的最大和」,那么很显然我们要求的答案就是:
35+
36+
$$
37+
\max_{0 \leq i \leq n-1} f[i]
38+
$$
39+
40+
那么我们如何求 $f[i]$ 呢?我们可以考虑 $nums[i]$ 单独成为一段还是加入 $f[i-1]$ 对应的那一段,这取决于 $nums[i]$ 和 $f[i-1] + nums[i]$ 哪个大,我们希望获得一个比较大的,于是可以写出这样的状态转移方程:
41+
42+
$$
43+
f[i] = \max(f[i-1] + nums[i], nums[i])
44+
$$
45+
46+
或者可以写成这样:
47+
48+
$$
49+
f[i] = \max(f[i-1], 0) + nums[i]
50+
$$
51+
52+
我们可以不用开一个数组来存储所有的计算结果,而是只用两个变量 $f$ 和 $ans$ 来维护对于每一个位置 $i$ 我们的最大值,这样我们可以省去空间复杂度的开销。
53+
54+
时间复杂度 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 为数组长度。
3555

3656
<!-- tabs:start -->
3757

@@ -40,59 +60,42 @@
4060
```python
4161
class Solution:
4262
def maxSubArray(self, nums: List[int]) -> int:
43-
n = len(nums)
44-
res = f = nums[0]
45-
for i in range(1, n):
46-
f = nums[i] + max(f, 0)
47-
res = max(res, f)
48-
return res
63+
ans, f = -inf, 0
64+
for x in nums:
65+
f = max(f, 0) + x
66+
ans = max(ans, f)
67+
return ans
4968
```
5069

5170
### **Java**
5271

5372
```java
5473
class Solution {
5574
public int maxSubArray(int[] nums) {
56-
int res = nums[0], f = nums[0];
57-
for (int i = 1, n = nums.length; i < n; ++i) {
58-
f = nums[i] + Math.max(f, 0);
59-
res = Math.max(res, f);
75+
int ans = Integer.MIN_VALUE;
76+
int f = 0;
77+
for (int x : nums) {
78+
f = Math.max(f, 0) + x;
79+
ans = Math.max(ans, f);
6080
}
61-
return res;
81+
return ans;
6282
}
6383
}
6484
```
6585

66-
### **JavaScript**
67-
68-
```js
69-
/**
70-
* @param {number[]} nums
71-
* @return {number}
72-
*/
73-
var maxSubArray = function (nums) {
74-
let res = nums[0];
75-
let f = nums[0];
76-
for (let i = 1; i < nums.length; ++i) {
77-
f = Math.max(f, 0) + nums[i];
78-
res = Math.max(res, f);
79-
}
80-
return res;
81-
};
82-
```
83-
8486
### **C++**
8587

8688
```cpp
8789
class Solution {
8890
public:
8991
int maxSubArray(vector<int>& nums) {
90-
int res = nums[0], f = nums[0];
91-
for (int i = 1; i < nums.size(); ++i) {
92-
f = max(f, 0) + nums[i];
93-
res = max(res, f);
92+
int ans = INT_MIN;
93+
int f = 0;
94+
for (int& x : nums) {
95+
f = max(f, 0) + x;
96+
ans = max(ans, f);
9497
}
95-
return res;
98+
return ans;
9699
}
97100
};
98101
```
@@ -101,19 +104,38 @@ public:
101104
102105
```go
103106
func maxSubArray(nums []int) int {
104-
f, res := nums[0], nums[0]
105-
for i := 1; i < len(nums); i++ {
106-
if f > 0 {
107-
f += nums[i]
108-
} else {
109-
f = nums[i]
110-
}
111-
if f > res {
112-
res = f
113-
}
114-
}
115-
return res
107+
ans, f := -1000000000, 0
108+
for _, x := range nums {
109+
f = max(f, 0) + x
110+
ans = max(ans, f)
111+
}
112+
return ans
116113
}
114+
115+
func max(a, b int) int {
116+
if a > b {
117+
return a
118+
}
119+
return b
120+
}
121+
```
122+
123+
### **JavaScript**
124+
125+
```js
126+
/**
127+
* @param {number[]} nums
128+
* @return {number}
129+
*/
130+
var maxSubArray = function (nums) {
131+
let ans = -1e10;
132+
let f = 0;
133+
for (const x of nums) {
134+
f = Math.max(f, 0) + x;
135+
ans = Math.max(ans, f);
136+
}
137+
return ans;
138+
};
117139
```
118140

119141
### **TypeScript**
@@ -149,12 +171,13 @@ impl Solution {
149171
```cs
150172
public class Solution {
151173
public int MaxSubArray(int[] nums) {
152-
int pre = 0, maxAns = nums[0];
174+
int ans = -1000000000;
175+
int f = 0;
153176
foreach (int x in nums) {
154-
pre = Math.Max(pre + x, x);
155-
maxAns = Math.Max(maxAns, pre);
177+
f = Math.Max(f, 0) + x;
178+
ans = Math.Max(ans, f);
156179
}
157-
return maxAns;
180+
return ans;
158181
}
159182
}
160183
```
Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
class Solution {
22
public:
33
int maxSubArray(vector<int>& nums) {
4-
int res = nums[0], f = nums[0];
5-
for (int i = 1; i < nums.size(); ++i) {
6-
f = max(f, 0) + nums[i];
7-
res = max(res, f);
4+
int ans = INT_MIN;
5+
int f = 0;
6+
for (int& x : nums) {
7+
f = max(f, 0) + x;
8+
ans = max(ans, f);
89
}
9-
return res;
10+
return ans;
1011
}
1112
};
Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
public class Solution {
22
public int MaxSubArray(int[] nums) {
3-
int pre = 0, maxAns = nums[0];
3+
int ans = -1000000000;
4+
int f = 0;
45
foreach (int x in nums) {
5-
pre = Math.Max(pre + x, x);
6-
maxAns = Math.Max(maxAns, pre);
6+
f = Math.Max(f, 0) + x;
7+
ans = Math.Max(ans, f);
78
}
8-
return maxAns;
9+
return ans;
910
}
1011
}
Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
func maxSubArray(nums []int) int {
2-
f, res := nums[0], nums[0]
3-
for i := 1; i < len(nums); i++ {
4-
if f > 0 {
5-
f += nums[i]
6-
} else {
7-
f = nums[i]
8-
}
9-
if f > res {
10-
res = f
11-
}
12-
}
13-
return res
2+
ans, f := -1000000000, 0
3+
for _, x := range nums {
4+
f = max(f, 0) + x
5+
ans = max(ans, f)
6+
}
7+
return ans
8+
}
9+
10+
func max(a, b int) int {
11+
if a > b {
12+
return a
13+
}
14+
return b
1415
}
Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
class Solution {
22
public int maxSubArray(int[] nums) {
3-
int res = nums[0], f = nums[0];
4-
for (int i = 1, n = nums.length; i < n; ++i) {
5-
f = nums[i] + Math.max(f, 0);
6-
res = Math.max(res, f);
3+
int ans = Integer.MIN_VALUE;
4+
int f = 0;
5+
for (int x : nums) {
6+
f = Math.max(f, 0) + x;
7+
ans = Math.max(ans, f);
78
}
8-
return res;
9+
return ans;
910
}
1011
}

lcof/面试题42. 连续子数组的最大和/Solution.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@
33
* @return {number}
44
*/
55
var maxSubArray = function (nums) {
6-
let res = nums[0];
7-
let f = nums[0];
8-
for (let i = 1; i < nums.length; ++i) {
9-
f = Math.max(f, 0) + nums[i];
10-
res = Math.max(res, f);
6+
let ans = -1e10;
7+
let f = 0;
8+
for (const x of nums) {
9+
f = Math.max(f, 0) + x;
10+
ans = Math.max(ans, f);
1111
}
12-
return res;
12+
return ans;
1313
};
Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
class Solution:
22
def maxSubArray(self, nums: List[int]) -> int:
3-
n = len(nums)
4-
res = f = nums[0]
5-
for i in range(1, n):
6-
f = nums[i] + max(f, 0)
7-
res = max(res, f)
8-
return res
3+
ans, f = -inf, 0
4+
for x in nums:
5+
f = max(f, 0) + x
6+
ans = max(ans, f)
7+
return ans

0 commit comments

Comments
 (0)