Skip to content

Commit 5de29d2

Browse files
committedJun 17, 2023
feat: add solutions to lc problem: No.0152
No.0152.Maximum Product Subarray
1 parent 01e5168 commit 5de29d2

File tree

10 files changed

+262
-229
lines changed

10 files changed

+262
-229
lines changed
 

‎solution/0100-0199/0152.Maximum Product Subarray/README.md

+92-80
Original file line numberDiff line numberDiff line change
@@ -43,16 +43,15 @@
4343

4444
<!-- 这里可写通用的实现逻辑 -->
4545

46-
考虑当前位置 i:
46+
**方法一:动态规划**
4747

48-
- 如果是一个负数的话,那么我们希望以它前一个位置结尾的某个段的积也是个负数,这样可以负负得正,并且我们希望这个积尽可能「负得更多」,即尽可能小。
49-
- 如果是一个正数的话,我们更希望以它前一个位置结尾的某个段的积也是个正数,并且希望它尽可能地大。
48+
我们定义两个变量 $f$ 和 $g$,其中 $f$ 表示以 $nums[i]$ 结尾的乘积最大子数组的乘积,而 $g$ 表示以 $nums[i]$ 结尾的乘积最小子数组的乘积。初始时 $f$ 和 $g$ 都等于 $nums[0]$。答案为所有 $f$ 中的最大值。
5049

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)$,然后继续计算下一个位置
5251

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)$。
5655

5756
<!-- tabs:start -->
5857

@@ -63,13 +62,13 @@
6362
```python
6463
class Solution:
6564
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
7372
```
7473

7574
### **Java**
@@ -79,52 +78,14 @@ class Solution:
7978
```java
8079
class Solution {
8180
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];
8382
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);
12687
}
127-
return res;
88+
return ans;
12889
}
12990
}
13091
```
@@ -135,14 +96,14 @@ public class Solution {
13596
class Solution {
13697
public:
13798
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];
139100
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);
144105
}
145-
return res;
106+
return ans;
146107
}
147108
};
148109
```
@@ -151,14 +112,14 @@ public:
151112
152113
```go
153114
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)
160121
}
161-
return res
122+
return ans
162123
}
163124
164125
func max(a, b int) int {
@@ -176,25 +137,76 @@ func min(a, b int) int {
176137
}
177138
```
178139

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+
179172
### **Rust**
180173

181174
```rust
182175
impl Solution {
183176
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);
192185
}
193-
res
186+
ans
194187
}
195188
}
196189
```
197190

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+
198210
### **...**
199211

200212
```

0 commit comments

Comments
 (0)