73
73
74
74
<!-- 这里可写通用的实现逻辑 -->
75
75
76
+ ** 方法一:枚举**
77
+
78
+ 我们可以枚举每一座塔作为最高塔,每一次向左右两边扩展,算出其他每个位置的高度,然后累加得到高度和 $t$。求出所有高度和的最大值即可。
79
+
80
+ 时间复杂度 $O(n^2)$,空间复杂度 $O(1)$。其中 $n$ 为数组 $maxHeights$ 的长度。
81
+
82
+ ** 方法二:动态规划 + 单调栈**
83
+
84
+ 方法一的做法足以通过本题,但是时间复杂度较高。我们可以使用“动态规划 + 单调栈”来优化枚举的过程。
85
+
86
+ 我们定义 $f[ i] $ 表示前 $i+1$ 座塔中,以最后一座塔作为最高塔的美丽塔方案的高度和。我们可以得到如下的状态转移方程:
87
+
88
+ $$
89
+ f[i]=
90
+ \begin{cases}
91
+ f[i-1]+heights[i],&\text{if } heights[i]\geq heights[i-1]\\
92
+ heights[i]\times(i-j)+f[j],&\text{if } heights[i]<heights[i-1]
93
+ \end{cases}
94
+ $$
95
+
96
+ 其中 $j$ 是最后一座塔左边第一个高度小于等于 $heights[ i] $ 的塔的下标。我们可以使用单调栈来维护这个下标。
97
+
98
+ 我们可以使用类似的方法求出 $g[ i] $,表示从右往左,以第 $i$ 座塔作为最高塔的美丽塔方案的高度和。最终答案即为 $f[ i] +g[ i] -heights[ i] $ 的最大值。
99
+
100
+ 时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 $maxHeights$ 的长度。
101
+
76
102
<!-- tabs:start -->
77
103
78
104
### ** Python3**
@@ -96,6 +122,44 @@ class Solution:
96
122
return ans
97
123
```
98
124
125
+ ``` python
126
+ class Solution :
127
+ def maximumSumOfHeights (self , maxHeights : List[int ]) -> int :
128
+ n = len (maxHeights)
129
+ stk = []
130
+ left = [- 1 ] * n
131
+ for i, x in enumerate (maxHeights):
132
+ while stk and maxHeights[stk[- 1 ]] > x:
133
+ stk.pop()
134
+ if stk:
135
+ left[i] = stk[- 1 ]
136
+ stk.append(i)
137
+ stk = []
138
+ right = [n] * n
139
+ for i in range (n - 1 , - 1 , - 1 ):
140
+ x = maxHeights[i]
141
+ while stk and maxHeights[stk[- 1 ]] >= x:
142
+ stk.pop()
143
+ if stk:
144
+ right[i] = stk[- 1 ]
145
+ stk.append(i)
146
+ f = [0 ] * n
147
+ for i, x in enumerate (maxHeights):
148
+ if i and x >= maxHeights[i - 1 ]:
149
+ f[i] = f[i - 1 ] + x
150
+ else :
151
+ j = left[i]
152
+ f[i] = x * (i - j) + (f[j] if j != - 1 else 0 )
153
+ g = [0 ] * n
154
+ for i in range (n - 1 , - 1 , - 1 ):
155
+ if i < n - 1 and maxHeights[i] >= maxHeights[i + 1 ]:
156
+ g[i] = g[i + 1 ] + maxHeights[i]
157
+ else :
158
+ j = right[i]
159
+ g[i] = maxHeights[i] * (j - i) + (g[j] if j != n else 0 )
160
+ return max (a + b - c for a, b, c in zip (f, g, maxHeights))
161
+ ```
162
+
99
163
### ** Java**
100
164
101
165
<!-- 这里可写当前语言的特殊实现逻辑 -->
@@ -124,6 +188,65 @@ class Solution {
124
188
}
125
189
```
126
190
191
+ ``` java
192
+ class Solution {
193
+ public long maximumSumOfHeights (List<Integer > maxHeights ) {
194
+ int n = maxHeights. size();
195
+ Deque<Integer > stk = new ArrayDeque<> ();
196
+ int [] left = new int [n];
197
+ int [] right = new int [n];
198
+ Arrays . fill(left, - 1 );
199
+ Arrays . fill(right, n);
200
+ for (int i = 0 ; i < n; ++ i) {
201
+ int x = maxHeights. get(i);
202
+ while (! stk. isEmpty() && maxHeights. get(stk. peek()) > x) {
203
+ stk. pop();
204
+ }
205
+ if (! stk. isEmpty()) {
206
+ left[i] = stk. peek();
207
+ }
208
+ stk. push(i);
209
+ }
210
+ stk. clear();
211
+ for (int i = n - 1 ; i >= 0 ; -- i) {
212
+ int x = maxHeights. get(i);
213
+ while (! stk. isEmpty() && maxHeights. get(stk. peek()) >= x) {
214
+ stk. pop();
215
+ }
216
+ if (! stk. isEmpty()) {
217
+ right[i] = stk. peek();
218
+ }
219
+ stk. push(i);
220
+ }
221
+ long [] f = new long [n];
222
+ long [] g = new long [n];
223
+ for (int i = 0 ; i < n; ++ i) {
224
+ int x = maxHeights. get(i);
225
+ if (i > 0 && x >= maxHeights. get(i - 1 )) {
226
+ f[i] = f[i - 1 ] + x;
227
+ } else {
228
+ int j = left[i];
229
+ f[i] = 1L * x * (i - j) + (j >= 0 ? f[j] : 0 );
230
+ }
231
+ }
232
+ for (int i = n - 1 ; i >= 0 ; -- i) {
233
+ int x = maxHeights. get(i);
234
+ if (i < n - 1 && x >= maxHeights. get(i + 1 )) {
235
+ g[i] = g[i + 1 ] + x;
236
+ } else {
237
+ int j = right[i];
238
+ g[i] = 1L * x * (j - i) + (j < n ? g[j] : 0 );
239
+ }
240
+ }
241
+ long ans = 0 ;
242
+ for (int i = 0 ; i < n; ++ i) {
243
+ ans = Math . max(ans, f[i] + g[i] - maxHeights. get(i));
244
+ }
245
+ return ans;
246
+ }
247
+ }
248
+ ```
249
+
127
250
### ** C++**
128
251
129
252
``` cpp
@@ -151,6 +274,63 @@ public:
151
274
};
152
275
```
153
276
277
+ ```cpp
278
+ class Solution {
279
+ public:
280
+ long long maximumSumOfHeights(vector<int>& maxHeights) {
281
+ int n = maxHeights.size();
282
+ stack<int> stk;
283
+ vector<int> left(n, -1);
284
+ vector<int> right(n, n);
285
+ for (int i = 0; i < n; ++i) {
286
+ int x = maxHeights[i];
287
+ while (!stk.empty() && maxHeights[stk.top()] > x) {
288
+ stk.pop();
289
+ }
290
+ if (!stk.empty()) {
291
+ left[i] = stk.top();
292
+ }
293
+ stk.push(i);
294
+ }
295
+ stk = stack<int>();
296
+ for (int i = n - 1; ~i; --i) {
297
+ int x = maxHeights[i];
298
+ while (!stk.empty() && maxHeights[stk.top()] >= x) {
299
+ stk.pop();
300
+ }
301
+ if (!stk.empty()) {
302
+ right[i] = stk.top();
303
+ }
304
+ stk.push(i);
305
+ }
306
+ long long f[n], g[n];
307
+ for (int i = 0; i < n; ++i) {
308
+ int x = maxHeights[i];
309
+ if (i && x >= maxHeights[i - 1]) {
310
+ f[i] = f[i - 1] + x;
311
+ } else {
312
+ int j = left[i];
313
+ f[i] = 1LL * x * (i - j) + (j != -1 ? f[j] : 0);
314
+ }
315
+ }
316
+ for (int i = n - 1; ~i; --i) {
317
+ int x = maxHeights[i];
318
+ if (i < n - 1 && x >= maxHeights[i + 1]) {
319
+ g[i] = g[i + 1] + x;
320
+ } else {
321
+ int j = right[i];
322
+ g[i] = 1LL * x * (j - i) + (j != n ? g[j] : 0);
323
+ }
324
+ }
325
+ long long ans = 0;
326
+ for (int i = 0; i < n; ++i) {
327
+ ans = max(ans, f[i] + g[i] - maxHeights[i]);
328
+ }
329
+ return ans;
330
+ }
331
+ };
332
+ ```
333
+
154
334
### ** Go**
155
335
156
336
``` go
@@ -187,6 +367,75 @@ func max(a, b int64) int64 {
187
367
}
188
368
```
189
369
370
+ ``` go
371
+ func maximumSumOfHeights (maxHeights []int ) (ans int64 ) {
372
+ n := len (maxHeights)
373
+ stk := []int {}
374
+ left := make ([]int , n)
375
+ right := make ([]int , n)
376
+ for i := range left {
377
+ left[i] = -1
378
+ right[i] = n
379
+ }
380
+ for i , x := range maxHeights {
381
+ for len (stk) > 0 && maxHeights[stk[len (stk)-1 ]] > x {
382
+ stk = stk[:len (stk)-1 ]
383
+ }
384
+ if len (stk) > 0 {
385
+ left[i] = stk[len (stk)-1 ]
386
+ }
387
+ stk = append (stk, i)
388
+ }
389
+ stk = []int {}
390
+ for i := n - 1 ; i >= 0 ; i-- {
391
+ x := maxHeights[i]
392
+ for len (stk) > 0 && maxHeights[stk[len (stk)-1 ]] >= x {
393
+ stk = stk[:len (stk)-1 ]
394
+ }
395
+ if len (stk) > 0 {
396
+ right[i] = stk[len (stk)-1 ]
397
+ }
398
+ stk = append (stk, i)
399
+ }
400
+ f := make ([]int64 , n)
401
+ g := make ([]int64 , n)
402
+ for i , x := range maxHeights {
403
+ if i > 0 && x >= maxHeights[i-1 ] {
404
+ f[i] = f[i-1 ] + int64 (x)
405
+ } else {
406
+ j := left[i]
407
+ f[i] = int64 (x) * int64 (i-j)
408
+ if j != -1 {
409
+ f[i] += f[j]
410
+ }
411
+ }
412
+ }
413
+ for i := n - 1 ; i >= 0 ; i-- {
414
+ x := maxHeights[i]
415
+ if i < n-1 && x >= maxHeights[i+1 ] {
416
+ g[i] = g[i+1 ] + int64 (x)
417
+ } else {
418
+ j := right[i]
419
+ g[i] = int64 (x) * int64 (j-i)
420
+ if j != n {
421
+ g[i] += g[j]
422
+ }
423
+ }
424
+ }
425
+ for i , x := range maxHeights {
426
+ ans = max (ans, f[i]+g[i]-int64 (x))
427
+ }
428
+ return
429
+ }
430
+
431
+ func max (a , b int64 ) int64 {
432
+ if a > b {
433
+ return a
434
+ }
435
+ return b
436
+ }
437
+ ```
438
+
190
439
### ** TypeScript**
191
440
192
441
``` ts
@@ -211,6 +460,61 @@ function maximumSumOfHeights(maxHeights: number[]): number {
211
460
}
212
461
```
213
462
463
+ ``` ts
464
+ function maximumSumOfHeights(maxHeights : number []): number {
465
+ const n = maxHeights .length ;
466
+ const stk: number [] = [];
467
+ const left: number [] = Array (n ).fill (- 1 );
468
+ const right: number [] = Array (n ).fill (n );
469
+ for (let i = 0 ; i < n ; ++ i ) {
470
+ const x = maxHeights [i ];
471
+ while (stk .length && maxHeights [stk .at (- 1 )] > x ) {
472
+ stk .pop ();
473
+ }
474
+ if (stk .length ) {
475
+ left [i ] = stk .at (- 1 );
476
+ }
477
+ stk .push (i );
478
+ }
479
+ stk .length = 0 ;
480
+ for (let i = n - 1 ; ~ i ; -- i ) {
481
+ const x = maxHeights [i ];
482
+ while (stk .length && maxHeights [stk .at (- 1 )] >= x ) {
483
+ stk .pop ();
484
+ }
485
+ if (stk .length ) {
486
+ right [i ] = stk .at (- 1 );
487
+ }
488
+ stk .push (i );
489
+ }
490
+ const f: number [] = Array (n ).fill (0 );
491
+ const g: number [] = Array (n ).fill (0 );
492
+ for (let i = 0 ; i < n ; ++ i ) {
493
+ const x = maxHeights [i ];
494
+ if (i && x >= maxHeights [i - 1 ]) {
495
+ f [i ] = f [i - 1 ] + x ;
496
+ } else {
497
+ const j = left [i ];
498
+ f [i ] = x * (i - j ) + (j >= 0 ? f [j ] : 0 );
499
+ }
500
+ }
501
+ for (let i = n - 1 ; ~ i ; -- i ) {
502
+ const x = maxHeights [i ];
503
+ if (i + 1 < n && x >= maxHeights [i + 1 ]) {
504
+ g [i ] = g [i + 1 ] + x ;
505
+ } else {
506
+ const j = right [i ];
507
+ g [i ] = x * (j - i ) + (j < n ? g [j ] : 0 );
508
+ }
509
+ }
510
+ let ans = 0 ;
511
+ for (let i = 0 ; i < n ; ++ i ) {
512
+ ans = Math .max (ans , f [i ] + g [i ] - maxHeights [i ]);
513
+ }
514
+ return ans ;
515
+ }
516
+ ```
517
+
214
518
### ** ...**
215
519
216
520
```
0 commit comments