51
51
52
52
<!-- 这里可写通用的实现逻辑 -->
53
53
54
- ### 1. 动态规划
54
+ ** 方法一: 动态规划**
55
55
56
- 设 ` dp [i]` 表示 ` [0..i] ` 中,以 ` nums[i] ` 结尾的最大子数组和,状态转移方程 ` dp[i ] = nums[i] + max(dp[i - 1], 0) ` 。
56
+ 我们定义 $f [ i] $ 表示以元素 $ nums[ i] $ 为结尾的连续子数组的最大和,初始时 $f [ 0 ] = nums[ 0 ] $,那么最终我们要求的答案即为 $\max _ {0 \leq i < n} f [ i ] $ 。
57
57
58
- 由于 ` dp [i]` 只与子问题 ` dp[i-1] ` 有关,故可以用一个变量 f 来表示。
58
+ 考虑 $f [ i] $,其中 $i \geq 1$,它的状态转移方程为:
59
59
60
- ### 2. 分治
60
+ $$
61
+ f[i] = \max \{ f[i - 1] + nums[i], nums[i] \}
62
+ $$
61
63
62
- 最大子数组和可能有三种情况 :
64
+ 也即 :
63
65
64
- 1 . 在数组左半部分
65
- 1 . 在数组右半部分
66
- 1 . 跨越左右半部分
66
+ $$
67
+ f[i] = \max \{ f[i - 1], 0 \} + nums[i]
68
+ $$
67
69
68
- 递归求得三者,返回最大值即可。
70
+ 由于 $f[ i] $ 只与 $f[ i - 1] $ 有关系,因此我们可以只用一个变量 $f$ 来维护对于当前 $f[ i] $ 的值是多少,然后进行状态转移即可。答案为 $\max_ {0 \leq i < n} f$。
71
+
72
+ 时间复杂度 $O(n)$,其中 $n$ 为数组 $nums$ 的长度。我们只需要遍历一遍数组即可求得答案。空间复杂度 $O(1)$,我们只需要常数空间存放若干变量。
69
73
70
74
<!-- tabs:start -->
71
75
72
76
### ** Python3**
73
77
74
78
<!-- 这里可写当前语言的特殊实现逻辑 -->
75
79
76
- 动态规划:
77
-
78
80
``` python
79
81
class Solution :
80
82
def maxSubArray (self , nums : List[int ]) -> int :
81
- res = f = nums[0 ]
82
- for num in nums[1 :]:
83
- f = num + max (f, 0 )
84
- res = max (res , f)
85
- return res
83
+ ans = f = nums[0 ]
84
+ for x in nums[1 :]:
85
+ f = max (f, 0 ) + x
86
+ ans = max (ans , f)
87
+ return ans
86
88
```
87
89
88
- 分治:
89
-
90
90
``` python
91
91
class Solution :
92
92
def maxSubArray (self , nums : List[int ]) -> int :
@@ -118,23 +118,19 @@ class Solution:
118
118
119
119
<!-- 这里可写当前语言的特殊实现逻辑 -->
120
120
121
- 动态规划:
122
-
123
121
``` java
124
122
class Solution {
125
123
public int maxSubArray (int [] nums ) {
126
- int f = nums[ 0 ], res = nums[0 ];
127
- for (int i = 1 , n = nums. length ; i < n ; ++ i) {
128
- f = nums[i] + Math . max(f, 0 );
129
- res = Math . max(res , f);
124
+ int ans = nums[0 ];
125
+ for (int i = 1 , f = nums[ 0 ] ; i < nums . length ; ++ i) {
126
+ f = Math . max(f, 0 ) + nums[i] ;
127
+ ans = Math . max(ans , f);
130
128
}
131
- return res ;
129
+ return ans ;
132
130
}
133
131
}
134
132
```
135
133
136
- 分治:
137
-
138
134
``` java
139
135
class Solution {
140
136
public int maxSubArray (int [] nums ) {
@@ -173,16 +169,49 @@ class Solution {
173
169
class Solution {
174
170
public:
175
171
int maxSubArray(vector<int >& nums) {
176
- int f = nums[ 0] , res = nums[ 0] ;
172
+ int ans = nums[ 0] , f = nums[ 0] ;
177
173
for (int i = 1; i < nums.size(); ++i) {
178
- f = nums [ i ] + max(f, 0);
179
- res = max(res , f);
174
+ f = max(f, 0) + nums [ i ] ;
175
+ ans = max(ans , f);
180
176
}
181
- return res ;
177
+ return ans ;
182
178
}
183
179
};
184
180
```
185
181
182
+ ### **Go**
183
+
184
+ ```go
185
+ func maxSubArray(nums []int) int {
186
+ ans, f := nums[0], nums[0]
187
+ for _, x := range nums[1:] {
188
+ f = max(f, 0) + x
189
+ ans = max(ans, f)
190
+ }
191
+ return ans
192
+ }
193
+
194
+ func max(a, b int) int {
195
+ if a > b {
196
+ return a
197
+ }
198
+ return b
199
+ }
200
+ ```
201
+
202
+ ### ** TypeScript**
203
+
204
+ ``` ts
205
+ function maxSubArray(nums : number []): number {
206
+ let [ans, f] = [nums [0 ], nums [0 ]];
207
+ for (let i = 1 ; i < nums .length ; ++ i ) {
208
+ f = Math .max (f , 0 ) + nums [i ];
209
+ ans = Math .max (ans , f );
210
+ }
211
+ return ans ;
212
+ }
213
+ ```
214
+
186
215
### ** JavaScript**
187
216
188
217
``` js
@@ -191,47 +220,26 @@ public:
191
220
* @return {number}
192
221
*/
193
222
var maxSubArray = function (nums ) {
194
- let f = nums[0],
195
- res = nums[0];
223
+ let [ans, f] = [nums[0 ], nums[0 ]];
196
224
for (let i = 1 ; i < nums .length ; ++ i) {
197
- f = nums[i] + Math.max(f, 0);
198
- res = Math.max(res , f);
225
+ f = Math .max (f, 0 ) + nums[i] ;
226
+ ans = Math .max (ans , f);
199
227
}
200
- return res ;
228
+ return ans ;
201
229
};
202
230
```
203
231
204
- ### ** Go**
205
-
206
- ``` go
207
- func maxSubArray (nums []int ) int {
208
- f , res := nums[0 ], nums[0 ]
209
- for i := 1 ; i < len (nums); i++ {
210
- if f > 0 {
211
- f += nums[i]
212
- } else {
213
- f = nums[i]
214
- }
215
- if f > res {
216
- res = f
217
- }
218
- }
219
- return res
220
- }
221
- ```
222
-
223
232
### ** C#**
224
233
225
234
``` cs
226
235
public class Solution {
227
236
public int MaxSubArray (int [] nums ) {
228
- int res = nums [0 ], f = nums [0 ];
229
- for (int i = 1 ; i < nums .Length ; ++ i )
230
- {
231
- f = nums [i ] + Math .Max (f , 0 );
232
- res = Math .Max (res , f );
237
+ int ans = nums [0 ], f = nums [0 ];
238
+ for (int i = 1 ; i < nums .Length ; ++ i ) {
239
+ f = Math .Max (f , 0 ) + nums [i ];
240
+ ans = Math .Max (ans , f );
233
241
}
234
- return res ;
242
+ return ans ;
235
243
}
236
244
}
237
245
```
@@ -242,14 +250,13 @@ public class Solution {
242
250
impl Solution {
243
251
pub fn max_sub_array (nums : Vec <i32 >) -> i32 {
244
252
let n = nums . len ();
245
- let mut res = nums [0 ];
246
- let mut sum = nums [0 ];
253
+ let mut ans = nums [0 ];
254
+ let mut f = nums [0 ];
247
255
for i in 1 .. n {
248
- let num = nums [i ];
249
- sum = num . max (sum + num );
250
- res = res . max (sum );
256
+ f = f . max (0 ) + nums [i ];
257
+ ans = ans . max (f );
251
258
}
252
- res
259
+ ans
253
260
}
254
261
}
255
262
```
0 commit comments