Skip to content

Commit ca289c7

Browse files
committed
feat: add solutions to lc problem: No.1856
No.1856.Maximum Subarray Min-Product
1 parent a615012 commit ca289c7

File tree

7 files changed

+237
-87
lines changed

7 files changed

+237
-87
lines changed

solution/1800-1899/1856.Maximum Subarray Min-Product/README.md

+84-31
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,13 @@
6262

6363
**方法一:单调栈 + 前缀和**
6464

65-
枚举每个元素 `nums[i]` 作为子数组的最小值,找出子数组的左右边界 `left[i]`, `right[i]`
65+
我们可以枚举每个元素 $nums[i]$ 作为子数组的最小值,找出子数组的左右边界 $left[i]$ 和 $right[i]$。其中 $left[i]$ 表示 $i$ 左侧第一个严格小于 $nums[i]$ 的位置,而 $right[i]$ 表示 $i$ 右侧第一个小于等于 $nums[i]$ 的位置
6666

67-
其中 `left[i]` 表示 i 左侧第一个严格小于 `nums[i]` 的位置,`right[i]` 表示 i 右侧第一个小于等于 `nums[i]` 的位置。`s[i]` 表示 nums 的前缀和数组
67+
为了方便地算出子数组的和,我们可以预处理出前缀和数组 $s$,其中 $s[i]$ 表示 $nums$ 前 $i$ 个元素的和
6868

69-
则以 `nums[i]` 作为子数组最小值的最小乘积为 `nums[i] * s[right[i]] - s[left[i] + 1]`
69+
那么以 $nums[i]$ 作为子数组最小值的最小乘积为 $nums[i] \times s[right[i]] - s[left[i] + 1]$。我们可以枚举每个元素 $nums[i]$,求出以 $nums[i]$ 作为子数组最小值的最小乘积,然后取最大值即可。
70+
71+
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 $nums$ 的长度。
7072

7173
<!-- tabs:start -->
7274

@@ -77,13 +79,12 @@
7779
```python
7880
class Solution:
7981
def maxSumMinProduct(self, nums: List[int]) -> int:
80-
mod = int(1e9) + 7
8182
n = len(nums)
8283
left = [-1] * n
8384
right = [n] * n
8485
stk = []
85-
for i, v in enumerate(nums):
86-
while stk and nums[stk[-1]] >= v:
86+
for i, x in enumerate(nums):
87+
while stk and nums[stk[-1]] >= x:
8788
stk.pop()
8889
if stk:
8990
left[i] = stk[-1]
@@ -95,9 +96,9 @@ class Solution:
9596
if stk:
9697
right[i] = stk[-1]
9798
stk.append(i)
98-
s = [0] + list(accumulate(nums))
99-
ans = max(v * (s[right[i]] - s[left[i] + 1]) for i, v in enumerate(nums))
100-
return ans % mod
99+
s = list(accumulate(nums, initial=0))
100+
mod = 10**9 + 7
101+
return max((s[right[i]] - s[left[i] + 1]) * x for i, x in enumerate(nums)) % mod
101102
```
102103

103104
### **Java**
@@ -138,10 +139,10 @@ class Solution {
138139
}
139140
long ans = 0;
140141
for (int i = 0; i < n; ++i) {
141-
long t = nums[i] * (s[right[i]] - s[left[i] + 1]);
142-
ans = Math.max(ans, t);
142+
ans = Math.max(ans, nums[i] * (s[right[i]] - s[left[i] + 1]));
143143
}
144-
return (int) (ans % 1000000007);
144+
final int mod = (int) 1e9 + 7;
145+
return (int) (ans % mod);
145146
}
146147
}
147148
```
@@ -157,25 +158,35 @@ public:
157158
vector<int> right(n, n);
158159
stack<int> stk;
159160
for (int i = 0; i < n; ++i) {
160-
while (!stk.empty() && nums[stk.top()] >= nums[i]) stk.pop();
161-
if (!stk.empty()) left[i] = stk.top();
161+
while (!stk.empty() && nums[stk.top()] >= nums[i]) {
162+
stk.pop();
163+
}
164+
if (!stk.empty()) {
165+
left[i] = stk.top();
166+
}
162167
stk.push(i);
163168
}
164169
stk = stack<int>();
165-
for (int i = n - 1; i >= 0; --i) {
166-
while (!stk.empty() && nums[stk.top()] > nums[i]) stk.pop();
167-
if (!stk.empty()) right[i] = stk.top();
170+
for (int i = n - 1; ~i; --i) {
171+
while (!stk.empty() && nums[stk.top()] > nums[i]) {
172+
stk.pop();
173+
}
174+
if (!stk.empty()) {
175+
right[i] = stk.top();
176+
}
168177
stk.push(i);
169178
}
170-
vector<long long> s(n + 1);
171-
for (int i = 0; i < n; ++i) s[i + 1] = s[i] + nums[i];
179+
long long s[n + 1];
180+
s[0] = 0;
181+
for (int i = 0; i < n; ++i) {
182+
s[i + 1] = s[i] + nums[i];
183+
}
172184
long long ans = 0;
173-
const int mod = 1e9 + 7;
174185
for (int i = 0; i < n; ++i) {
175-
long long t = nums[i] * (s[right[i]] - s[left[i] + 1]);
176-
ans = max(ans, t);
186+
ans = max(ans, nums[i] * (s[right[i]] - s[left[i] + 1]));
177187
}
178-
return (int)(ans % mod);
188+
const int mod = 1e9 + 7;
189+
return ans % mod;
179190
}
180191
};
181192
```
@@ -192,8 +203,8 @@ func maxSumMinProduct(nums []int) int {
192203
right[i] = n
193204
}
194205
stk := []int{}
195-
for i, v := range nums {
196-
for len(stk) > 0 && nums[stk[len(stk)-1]] >= v {
206+
for i, x := range nums {
207+
for len(stk) > 0 && nums[stk[len(stk)-1]] >= x {
197208
stk = stk[:len(stk)-1]
198209
}
199210
if len(stk) > 0 {
@@ -212,21 +223,63 @@ func maxSumMinProduct(nums []int) int {
212223
stk = append(stk, i)
213224
}
214225
s := make([]int, n+1)
215-
for i, v := range nums {
216-
s[i+1] = s[i] + v
226+
for i, x := range nums {
227+
s[i+1] = s[i] + x
217228
}
218229
ans := 0
219-
for i, v := range nums {
220-
t := v * (s[right[i]] - s[left[i]+1])
221-
if ans < t {
230+
for i, x := range nums {
231+
if t := x * (s[right[i]] - s[left[i]+1]); ans < t {
222232
ans = t
223233
}
224234
}
225-
mod := int(1e9) + 7
235+
const mod = 1e9 + 7
226236
return ans % mod
227237
}
228238
```
229239

240+
### **TypeSript**
241+
242+
```ts
243+
function maxSumMinProduct(nums: number[]): number {
244+
const n = nums.length;
245+
const left: number[] = new Array(n).fill(-1);
246+
const right: number[] = new Array(n).fill(n);
247+
let stk: number[] = [];
248+
for (let i = 0; i < n; ++i) {
249+
while (stk.length && nums[stk[stk.length - 1]] >= nums[i]) {
250+
stk.pop();
251+
}
252+
if (stk.length) {
253+
left[i] = stk[stk.length - 1];
254+
}
255+
stk.push(i);
256+
}
257+
stk = [];
258+
for (let i = n - 1; i >= 0; --i) {
259+
while (stk.length && nums[stk[stk.length - 1]] > nums[i]) {
260+
stk.pop();
261+
}
262+
if (stk.length) {
263+
right[i] = stk[stk.length - 1];
264+
}
265+
stk.push(i);
266+
}
267+
const s: number[] = new Array(n + 1).fill(0);
268+
for (let i = 0; i < n; ++i) {
269+
s[i + 1] = s[i] + nums[i];
270+
}
271+
let ans: bigint = 0n;
272+
const mod = 10 ** 9 + 7;
273+
for (let i = 0; i < n; ++i) {
274+
const t = BigInt(nums[i]) * BigInt(s[right[i]] - s[left[i] + 1]);
275+
if (ans < t) {
276+
ans = t;
277+
}
278+
}
279+
return Number(ans % BigInt(mod));
280+
}
281+
```
282+
230283
### **...**
231284

232285
```

solution/1800-1899/1856.Maximum Subarray Min-Product/README_EN.md

+79-28
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,12 @@
6161
```python
6262
class Solution:
6363
def maxSumMinProduct(self, nums: List[int]) -> int:
64-
mod = int(1e9) + 7
6564
n = len(nums)
6665
left = [-1] * n
6766
right = [n] * n
6867
stk = []
69-
for i, v in enumerate(nums):
70-
while stk and nums[stk[-1]] >= v:
68+
for i, x in enumerate(nums):
69+
while stk and nums[stk[-1]] >= x:
7170
stk.pop()
7271
if stk:
7372
left[i] = stk[-1]
@@ -79,9 +78,9 @@ class Solution:
7978
if stk:
8079
right[i] = stk[-1]
8180
stk.append(i)
82-
s = [0] + list(accumulate(nums))
83-
ans = max(v * (s[right[i]] - s[left[i] + 1]) for i, v in enumerate(nums))
84-
return ans % mod
81+
s = list(accumulate(nums, initial=0))
82+
mod = 10**9 + 7
83+
return max((s[right[i]] - s[left[i] + 1]) * x for i, x in enumerate(nums)) % mod
8584
```
8685

8786
### **Java**
@@ -120,10 +119,10 @@ class Solution {
120119
}
121120
long ans = 0;
122121
for (int i = 0; i < n; ++i) {
123-
long t = nums[i] * (s[right[i]] - s[left[i] + 1]);
124-
ans = Math.max(ans, t);
122+
ans = Math.max(ans, nums[i] * (s[right[i]] - s[left[i] + 1]));
125123
}
126-
return (int) (ans % 1000000007);
124+
final int mod = (int) 1e9 + 7;
125+
return (int) (ans % mod);
127126
}
128127
}
129128
```
@@ -139,25 +138,35 @@ public:
139138
vector<int> right(n, n);
140139
stack<int> stk;
141140
for (int i = 0; i < n; ++i) {
142-
while (!stk.empty() && nums[stk.top()] >= nums[i]) stk.pop();
143-
if (!stk.empty()) left[i] = stk.top();
141+
while (!stk.empty() && nums[stk.top()] >= nums[i]) {
142+
stk.pop();
143+
}
144+
if (!stk.empty()) {
145+
left[i] = stk.top();
146+
}
144147
stk.push(i);
145148
}
146149
stk = stack<int>();
147-
for (int i = n - 1; i >= 0; --i) {
148-
while (!stk.empty() && nums[stk.top()] > nums[i]) stk.pop();
149-
if (!stk.empty()) right[i] = stk.top();
150+
for (int i = n - 1; ~i; --i) {
151+
while (!stk.empty() && nums[stk.top()] > nums[i]) {
152+
stk.pop();
153+
}
154+
if (!stk.empty()) {
155+
right[i] = stk.top();
156+
}
150157
stk.push(i);
151158
}
152-
vector<long long> s(n + 1);
153-
for (int i = 0; i < n; ++i) s[i + 1] = s[i] + nums[i];
159+
long long s[n + 1];
160+
s[0] = 0;
161+
for (int i = 0; i < n; ++i) {
162+
s[i + 1] = s[i] + nums[i];
163+
}
154164
long long ans = 0;
155-
const int mod = 1e9 + 7;
156165
for (int i = 0; i < n; ++i) {
157-
long long t = nums[i] * (s[right[i]] - s[left[i] + 1]);
158-
ans = max(ans, t);
166+
ans = max(ans, nums[i] * (s[right[i]] - s[left[i] + 1]));
159167
}
160-
return (int)(ans % mod);
168+
const int mod = 1e9 + 7;
169+
return ans % mod;
161170
}
162171
};
163172
```
@@ -174,8 +183,8 @@ func maxSumMinProduct(nums []int) int {
174183
right[i] = n
175184
}
176185
stk := []int{}
177-
for i, v := range nums {
178-
for len(stk) > 0 && nums[stk[len(stk)-1]] >= v {
186+
for i, x := range nums {
187+
for len(stk) > 0 && nums[stk[len(stk)-1]] >= x {
179188
stk = stk[:len(stk)-1]
180189
}
181190
if len(stk) > 0 {
@@ -194,21 +203,63 @@ func maxSumMinProduct(nums []int) int {
194203
stk = append(stk, i)
195204
}
196205
s := make([]int, n+1)
197-
for i, v := range nums {
198-
s[i+1] = s[i] + v
206+
for i, x := range nums {
207+
s[i+1] = s[i] + x
199208
}
200209
ans := 0
201-
for i, v := range nums {
202-
t := v * (s[right[i]] - s[left[i]+1])
203-
if ans < t {
210+
for i, x := range nums {
211+
if t := x * (s[right[i]] - s[left[i]+1]); ans < t {
204212
ans = t
205213
}
206214
}
207-
mod := int(1e9) + 7
215+
const mod = 1e9 + 7
208216
return ans % mod
209217
}
210218
```
211219

220+
### **TypeSript**
221+
222+
```ts
223+
function maxSumMinProduct(nums: number[]): number {
224+
const n = nums.length;
225+
const left: number[] = new Array(n).fill(-1);
226+
const right: number[] = new Array(n).fill(n);
227+
let stk: number[] = [];
228+
for (let i = 0; i < n; ++i) {
229+
while (stk.length && nums[stk[stk.length - 1]] >= nums[i]) {
230+
stk.pop();
231+
}
232+
if (stk.length) {
233+
left[i] = stk[stk.length - 1];
234+
}
235+
stk.push(i);
236+
}
237+
stk = [];
238+
for (let i = n - 1; i >= 0; --i) {
239+
while (stk.length && nums[stk[stk.length - 1]] > nums[i]) {
240+
stk.pop();
241+
}
242+
if (stk.length) {
243+
right[i] = stk[stk.length - 1];
244+
}
245+
stk.push(i);
246+
}
247+
const s: number[] = new Array(n + 1).fill(0);
248+
for (let i = 0; i < n; ++i) {
249+
s[i + 1] = s[i] + nums[i];
250+
}
251+
let ans: bigint = 0n;
252+
const mod = 10 ** 9 + 7;
253+
for (let i = 0; i < n; ++i) {
254+
const t = BigInt(nums[i]) * BigInt(s[right[i]] - s[left[i] + 1]);
255+
if (ans < t) {
256+
ans = t;
257+
}
258+
}
259+
return Number(ans % BigInt(mod));
260+
}
261+
```
262+
212263
### **...**
213264

214265
```

0 commit comments

Comments
 (0)