@@ -515,20 +515,66 @@ class Solution:
515
515
``` python3
516
516
class Solution :
517
517
def trap (self , height : List[int ]) -> int :
518
- st = [0 ]
518
+ # 单调栈
519
+ '''
520
+ 单调栈是按照 行 的方向来计算雨水
521
+ 从栈顶到栈底的顺序:从小到大
522
+ 通过三个元素来接水:栈顶,栈顶的下一个元素,以及即将入栈的元素
523
+ 雨水高度是 min(凹槽左边高度, 凹槽右边高度) - 凹槽底部高度
524
+ 雨水的宽度是 凹槽右边的下标 - 凹槽左边的下标 - 1(因为只求中间宽度)
525
+ '''
526
+ # stack储存index,用于计算对应的柱子高度
527
+ stack = [0 ]
519
528
result = 0
520
- for i in range (1 ,len (height)):
521
- while st!= [] and height[i]> height[st[- 1 ]]:
522
- midh = height[st[- 1 ]]
523
- st.pop()
524
- if st!= []:
525
- hright = height[i]
526
- hleft = height[st[- 1 ]]
527
- h = min (hright,hleft)- midh
528
- w = i- st[- 1 ]- 1
529
- result+= h* w
530
- st.append(i)
529
+ for i in range (1 , len (height)):
530
+ # 情况一
531
+ if height[i] < height[stack[- 1 ]]:
532
+ stack.append(i)
533
+
534
+ # 情况二
535
+ # 当当前柱子高度和栈顶一致时,左边的一个是不可能存放雨水的,所以保留右侧新柱子
536
+ # 需要使用最右边的柱子来计算宽度
537
+ elif height[i] == height[stack[- 1 ]]:
538
+ stack.pop()
539
+ stack.append(i)
540
+
541
+ # 情况三
542
+ else :
543
+ # 抛出所有较低的柱子
544
+ while stack and height[i] > height[stack[- 1 ]]:
545
+ # 栈顶就是中间的柱子:储水槽,就是凹槽的地步
546
+ mid_height = height[stack[- 1 ]]
547
+ stack.pop()
548
+ if stack:
549
+ right_height = height[i]
550
+ left_height = height[stack[- 1 ]]
551
+ # 两侧的较矮一方的高度 - 凹槽底部高度
552
+ h = min (right_height, left_height) - mid_height
553
+ # 凹槽右侧下标 - 凹槽左侧下标 - 1: 只求中间宽度
554
+ w = i - stack[- 1 ] - 1
555
+ # 体积:高乘宽
556
+ result += h * w
557
+ stack.append(i)
531
558
return result
559
+
560
+ # 单调栈压缩版
561
+ class Solution :
562
+ def trap (self , height : List[int ]) -> int :
563
+ stack = [0 ]
564
+ result = 0
565
+ for i in range (1 , len (height)):
566
+ while stack and height[i] > height[stack[- 1 ]]:
567
+ mid_height = stack.pop()
568
+ if stack:
569
+ # 雨水高度是 min(凹槽左侧高度, 凹槽右侧高度) - 凹槽底部高度
570
+ h = min (height[stack[- 1 ]], height[i]) - height[mid_height]
571
+ # 雨水宽度是 凹槽右侧的下标 - 凹槽左侧的下标 - 1
572
+ w = i - stack[- 1 ] - 1
573
+ # 累计总雨水体积
574
+ result += h * w
575
+ stack.append(i)
576
+ return result
577
+
532
578
```
533
579
534
580
Go:
0 commit comments