62
62
63
63
** 方法一:单调栈 + 前缀和**
64
64
65
- 枚举每个元素 ` nums[i] ` 作为子数组的最小值,找出子数组的左右边界 ` left[i] ` , ` right[i] ` 。
65
+ 我们可以枚举每个元素 $ nums[ i] $ 作为子数组的最小值,找出子数组的左右边界 $ left[ i] $ 和 $ right[ i] $。其中 $left [ i ] $ 表示 $i$ 左侧第一个严格小于 $nums [ i ] $ 的位置,而 $right [ i ] $ 表示 $i$ 右侧第一个小于等于 $nums [ i ] $ 的位置 。
66
66
67
- 其中 ` left [i]` 表示 i 左侧第一个严格小于 ` nums[i] ` 的位置, ` right[i] ` 表示 i 右侧第一个小于等于 ` nums[i] ` 的位置。 ` s[i] ` 表示 nums 的前缀和数组 。
67
+ 为了方便地算出子数组的和,我们可以预处理出前缀和数组 $s$, 其中 $s [ i] $ 表示 $ nums$ 前 $i$ 个元素的和 。
68
68
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$ 的长度。
70
72
71
73
<!-- tabs:start -->
72
74
77
79
``` python
78
80
class Solution :
79
81
def maxSumMinProduct (self , nums : List[int ]) -> int :
80
- mod = int (1e9 ) + 7
81
82
n = len (nums)
82
83
left = [- 1 ] * n
83
84
right = [n] * n
84
85
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 :
87
88
stk.pop()
88
89
if stk:
89
90
left[i] = stk[- 1 ]
@@ -95,9 +96,9 @@ class Solution:
95
96
if stk:
96
97
right[i] = stk[- 1 ]
97
98
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
101
102
```
102
103
103
104
### ** Java**
@@ -138,10 +139,10 @@ class Solution {
138
139
}
139
140
long ans = 0 ;
140
141
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 ]));
143
143
}
144
- return (int ) (ans % 1000000007 );
144
+ final int mod = (int ) 1e9 + 7 ;
145
+ return (int ) (ans % mod);
145
146
}
146
147
}
147
148
```
@@ -157,25 +158,35 @@ public:
157
158
vector<int > right(n, n);
158
159
stack<int > stk;
159
160
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
+ }
162
167
stk.push(i);
163
168
}
164
169
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
+ }
168
177
stk.push(i);
169
178
}
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
+ }
172
184
long long ans = 0;
173
- const int mod = 1e9 + 7;
174
185
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] ));
177
187
}
178
- return (int)(ans % mod);
188
+ const int mod = 1e9 + 7;
189
+ return ans % mod;
179
190
}
180
191
};
181
192
```
@@ -192,8 +203,8 @@ func maxSumMinProduct(nums []int) int {
192
203
right[i] = n
193
204
}
194
205
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 {
197
208
stk = stk[:len(stk)-1]
198
209
}
199
210
if len(stk) > 0 {
@@ -212,21 +223,63 @@ func maxSumMinProduct(nums []int) int {
212
223
stk = append(stk, i)
213
224
}
214
225
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
217
228
}
218
229
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 {
222
232
ans = t
223
233
}
224
234
}
225
- mod := int( 1e9) + 7
235
+ const mod = 1e9 + 7
226
236
return ans % mod
227
237
}
228
238
```
229
239
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
+
230
283
### ** ...**
231
284
232
285
```
0 commit comments