42. 接雨水

摘要
Title: 42. 接雨水
Categories: 单调栈

Powered by:NEFU AB-IN

Link

42. 接雨水

题意

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。

思路

单调栈经典题
一个坑是否能存水,取决于自己,和两边第一个比自己高的柱子

所以很适合从左到右遍历,求这个坑第一个右边比自己高的柱子,同时也要有左边比自己高的柱子,那么正好可以在栈中的下一个数,因为我们遍历栈的时候,里面都是没找到右边第一个高的柱子的柱子,且单调递减,所以栈的下一个元素就是左端点,那么水坑的体积就可以算出来

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
'''
Author: NEFU AB-IN
Date: 2024-08-26 21:33:53
FilePath: \LeetCode\42\42.py
LastEditTime: 2024-08-27 21:01:52
'''
# 3.8.19 import
import random
from collections import Counter, defaultdict, deque
from datetime import datetime, timedelta
from functools import lru_cache, reduce
from heapq import heapify, heappop, heappush, nlargest, nsmallest
from itertools import combinations, compress, permutations, starmap, tee
from math import ceil, comb, fabs, floor, gcd, hypot, log, perm, sqrt
from string import ascii_lowercase, ascii_uppercase
from sys import exit, setrecursionlimit, stdin
from typing import Any, Callable, Dict, List, Optional, Tuple, TypeVar, Union

# Constants
TYPE = TypeVar('TYPE')
N = int(2e5 + 10)
M = int(20)
INF = int(1e12)
OFFSET = int(100)
MOD = int(1e9 + 7)

# Set recursion limit
setrecursionlimit(int(2e9))


class Arr:
array = staticmethod(lambda x=0, size=N: [x() if callable(x) else x for _ in range(size)])
array2d = staticmethod(lambda x=0, rows=N, cols=M: [Arr.array(x, cols) for _ in range(rows)])
graph = staticmethod(lambda size=N: [[] for _ in range(size)])


class Math:
max = staticmethod(lambda a, b: a if a > b else b)
min = staticmethod(lambda a, b: a if a < b else b)


class Std:
pass

# ————————————————————— Division line ——————————————————————


class Solution:
def trap(self, heights: List[int]) -> int:
ans = 0
stack_ = []

for right, h in enumerate(heights):
while stack_ and h > heights[stack_[-1]]:
mid = heights[stack_.pop()]
if not stack_:
break
left = stack_[-1]
ans += (Math.min(heights[left], h) - mid) * (right - left - 1)
stack_.append(right)
return ans

使用搜索:谷歌必应百度