43
43
44
44
<!-- 这里可写通用的实现逻辑 -->
45
45
46
- 考虑当前位置 i:
46
+ ** 方法一:动态规划 **
47
47
48
- - 如果是一个负数的话,那么我们希望以它前一个位置结尾的某个段的积也是个负数,这样可以负负得正,并且我们希望这个积尽可能「负得更多」,即尽可能小。
49
- - 如果是一个正数的话,我们更希望以它前一个位置结尾的某个段的积也是个正数,并且希望它尽可能地大。
48
+ 我们定义两个变量 $f$ 和 $g$,其中 $f$ 表示以 $nums[ i] $ 结尾的乘积最大子数组的乘积,而 $g$ 表示以 $nums[ i] $ 结尾的乘积最小子数组的乘积。初始时 $f$ 和 $g$ 都等于 $nums[ 0] $。答案为所有 $f$ 中的最大值。
50
49
51
- 因此,分别维护 fmax 和 fmin 。
50
+ 从 $i=1$ 开始,我们可以考虑将第 $i$ 个数 $nums [ i ] $ 添加到前面的乘积最大或者乘积最小的子数组乘积的后面,或者单独作为一个子数组乘积(即此时子数组长度只有 $1$)。我们将此前的乘积最大值记为 $ff$,乘积最小值记为 $gg$,那么 $f = \max(f, ff \times nums [ i ] , gg \times nums [ i ] )$,而 $g = \min(g, ff \times nums [ i ] , gg \times nums [ i ] )$。接下来,我们更新答案 $ans = \max(ans, f)$,然后继续计算下一个位置 。
52
51
53
- - ` fmax(i) = max(nums[i], fmax(i - 1) * nums[i], fmin(i - 1) * nums[i]) `
54
- - ` fmin(i) = min(nums[i], fmax(i - 1) * nums[i], fmin(i - 1) * nums[i]) `
55
- - ` res = max(fmax(i)), i∈[0, n) `
52
+ 最后的答案即为 $ans$。
53
+
54
+ 时间复杂度 $O(n)$,其中 $n$ 是数组 $nums$ 的长度。我们只需要遍历数组一次即可求得答案。空间复杂度 $O(1)$。
56
55
57
56
<!-- tabs:start -->
58
57
63
62
``` python
64
63
class Solution :
65
64
def maxProduct (self , nums : List[int ]) -> int :
66
- maxf = minf = res = nums[0 ]
67
- for num in nums[1 :]:
68
- m, n = maxf, minf
69
- maxf = max (num, m * num, n * num )
70
- minf = min (num, m * num, n * num )
71
- res = max (res, maxf )
72
- return res
65
+ ans = f = g = nums[0 ]
66
+ for x in nums[1 :]:
67
+ ff, gg = f, g
68
+ f = max (x, ff * x, gg * x )
69
+ g = min (x, ff * x, gg * x )
70
+ ans = max (ans, f )
71
+ return ans
73
72
```
74
73
75
74
### ** Java**
@@ -79,52 +78,14 @@ class Solution:
79
78
``` java
80
79
class Solution {
81
80
public int maxProduct (int [] nums ) {
82
- int maxf = nums[0 ], minf = nums[0 ], res = nums[0 ];
81
+ int f = nums[0 ], g = nums[0 ], ans = nums[0 ];
83
82
for (int i = 1 ; i < nums. length; ++ i) {
84
- int m = maxf, n = minf;
85
- maxf = Math . max(nums[i], Math . max(m * nums[i], n * nums[i]));
86
- minf = Math . min(nums[i], Math . min(m * nums[i], n * nums[i]));
87
- res = Math . max(res, maxf);
88
- }
89
- return res;
90
- }
91
- }
92
- ```
93
-
94
- ### ** TypeScript**
95
-
96
- ``` ts
97
- function maxProduct(nums : number []): number {
98
- let n = nums .length ;
99
- let preMax = nums [0 ],
100
- preMin = nums [0 ],
101
- ans = nums [0 ];
102
- for (let i = 1 ; i < n ; ++ i ) {
103
- let cur = nums [i ];
104
- let x = preMax ,
105
- y = preMin ;
106
- preMax = Math .max (x * cur , y * cur , cur );
107
- preMin = Math .min (x * cur , y * cur , cur );
108
- ans = Math .max (preMax , ans );
109
- }
110
- return ans ;
111
- }
112
- ```
113
-
114
- ### ** C#**
115
-
116
- ``` cs
117
- public class Solution {
118
- public int MaxProduct (int [] nums ) {
119
- int maxf = nums [0 ], minf = nums [0 ], res = nums [0 ];
120
- for (int i = 1 ; i < nums .Length ; ++ i )
121
- {
122
- int m = maxf , n = minf ;
123
- maxf = Math .Max (nums [i ], Math .Max (nums [i ] * m , nums [i ] * n ));
124
- minf = Math .Min (nums [i ], Math .Min (nums [i ] * m , nums [i ] * n ));
125
- res = Math .Max (res , maxf );
83
+ int ff = f, gg = g;
84
+ f = Math . max(nums[i], Math . max(ff * nums[i], gg * nums[i]));
85
+ g = Math . min(nums[i], Math . min(ff * nums[i], gg * nums[i]));
86
+ ans = Math . max(ans, f);
126
87
}
127
- return res ;
88
+ return ans ;
128
89
}
129
90
}
130
91
```
@@ -135,14 +96,14 @@ public class Solution {
135
96
class Solution {
136
97
public:
137
98
int maxProduct(vector<int >& nums) {
138
- int maxf = nums[ 0] , minf = nums[ 0] , res = nums[ 0] ;
99
+ int f = nums[ 0] , g = nums[ 0] , ans = nums[ 0] ;
139
100
for (int i = 1; i < nums.size(); ++i) {
140
- int m = maxf, n = minf ;
141
- maxf = max(nums[ i] , max( nums[ i] * m, nums[ i] * n) );
142
- minf = min(nums[ i] , min( nums[ i] * m, nums[ i] * n) );
143
- res = max(res, maxf );
101
+ int ff = f, gg = g ;
102
+ f = max({ nums[ i] , ff * nums[ i] , gg * nums[ i] } );
103
+ g = min({ nums[ i] , ff * nums[ i] , gg * nums[ i] } );
104
+ ans = max(ans, f );
144
105
}
145
- return res ;
106
+ return ans ;
146
107
}
147
108
};
148
109
```
@@ -151,14 +112,14 @@ public:
151
112
152
113
```go
153
114
func maxProduct(nums []int) int {
154
- maxf, minf, res := nums[0], nums[0], nums[0]
155
- for i := 1; i < len( nums); i++ {
156
- m, n := maxf, minf
157
- maxf = max(nums[i] , max(nums[i]*m, nums[i]*n ))
158
- minf = min(nums[i] , min(nums[i]*m, nums[i]*n ))
159
- res = max(res, maxf )
115
+ f, g, ans := nums[0], nums[0], nums[0]
116
+ for _, x := range nums[1:] {
117
+ ff, gg := f, g
118
+ f = max(x , max(ff*x, gg*x ))
119
+ g = min(x , min(ff*x, gg*x ))
120
+ ans = max(ans, f )
160
121
}
161
- return res
122
+ return ans
162
123
}
163
124
164
125
func max(a, b int) int {
@@ -176,25 +137,76 @@ func min(a, b int) int {
176
137
}
177
138
```
178
139
140
+ ### ** TypeScript**
141
+
142
+ ``` ts
143
+ function maxProduct(nums : number []): number {
144
+ let [f, g, ans] = [nums [0 ], nums [0 ], nums [0 ]];
145
+ for (let i = 1 ; i < nums .length ; ++ i ) {
146
+ const [ff, gg] = [f , g ];
147
+ f = Math .max (nums [i ], ff * nums [i ], gg * nums [i ]);
148
+ g = Math .min (nums [i ], ff * nums [i ], gg * nums [i ]);
149
+ ans = Math .max (ans , f );
150
+ }
151
+ return ans ;
152
+ }
153
+ ```
154
+
155
+ ### ** C#**
156
+
157
+ ``` cs
158
+ public class Solution {
159
+ public int MaxProduct (int [] nums ) {
160
+ int f = nums [0 ], g = nums [0 ], ans = nums [0 ];
161
+ for (int i = 1 ; i < nums .Length ; ++ i ) {
162
+ int ff = f , gg = g ;
163
+ f = Math .Max (nums [i ], Math .Max (ff * nums [i ], gg * nums [i ]));
164
+ g = Math .Min (nums [i ], Math .Min (ff * nums [i ], gg * nums [i ]));
165
+ ans = Math .Max (ans , f );
166
+ }
167
+ return ans ;
168
+ }
169
+ }
170
+ ```
171
+
179
172
### ** Rust**
180
173
181
174
``` rust
182
175
impl Solution {
183
176
pub fn max_product (nums : Vec <i32 >) -> i32 {
184
- let mut min = nums [0 ];
185
- let mut max = nums [0 ];
186
- let mut res = nums [0 ];
187
- for & num in nums . iter (). skip (1 ) {
188
- let (pre_min , pre_max ) = (min , max );
189
- min = num . min ( num * pre_min ) . min ( num * pre_max );
190
- max = num . max ( num * pre_min ) . max ( num * pre_max );
191
- res = res . max (max );
177
+ let mut f = nums [0 ];
178
+ let mut g = nums [0 ];
179
+ let mut ans = nums [0 ];
180
+ for & x in nums . iter (). skip (1 ) {
181
+ let (ff , gg ) = (f , g );
182
+ f = x . max ( x * ff ) . max ( x * gg );
183
+ g = x . min ( x * ff ) . min ( x * gg );
184
+ ans = ans . max (f );
192
185
}
193
- res
186
+ ans
194
187
}
195
188
}
196
189
```
197
190
191
+ ### ** JavaScript**
192
+
193
+ ``` js
194
+ /**
195
+ * @param {number[]} nums
196
+ * @return {number}
197
+ */
198
+ var maxProduct = function (nums ) {
199
+ let [f, g, ans] = [nums[0 ], nums[0 ], nums[0 ]];
200
+ for (let i = 1 ; i < nums .length ; ++ i) {
201
+ const [ff , gg ] = [f, g];
202
+ f = Math .max (nums[i], ff * nums[i], gg * nums[i]);
203
+ g = Math .min (nums[i], ff * nums[i], gg * nums[i]);
204
+ ans = Math .max (ans, f);
205
+ }
206
+ return ans;
207
+ };
208
+ ```
209
+
198
210
### ** ...**
199
211
200
212
```
0 commit comments