From 1ab2f9bc5b44457f6c711e6957d2e770b9570661 Mon Sep 17 00:00:00 2001 From: Asterisk <44215173+casnz1601@users.noreply.github.com> Date: Wed, 29 Sep 2021 18:24:09 +0800 Subject: [PATCH] =?UTF-8?q?Update=200042.=E6=8E=A5=E9=9B=A8=E6=B0=B4.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 补充python备注,和规范python代码 --- problems/0042.接雨水.md | 70 +++++++++++++++++++++++++++++++------- 1 file changed, 58 insertions(+), 12 deletions(-) diff --git a/problems/0042.接雨水.md b/problems/0042.接雨水.md index f0d0ecb3..bc397863 100644 --- a/problems/0042.接雨水.md +++ b/problems/0042.接雨水.md @@ -515,20 +515,66 @@ class Solution: ```python3 class Solution: def trap(self, height: List[int]) -> int: - st =[0] + # 单调栈 + ''' + 单调栈是按照 行 的方向来计算雨水 + 从栈顶到栈底的顺序:从小到大 + 通过三个元素来接水:栈顶,栈顶的下一个元素,以及即将入栈的元素 + 雨水高度是 min(凹槽左边高度, 凹槽右边高度) - 凹槽底部高度 + 雨水的宽度是 凹槽右边的下标 - 凹槽左边的下标 - 1(因为只求中间宽度) + ''' + # stack储存index,用于计算对应的柱子高度 + stack = [0] result = 0 - for i in range(1,len(height)): - while st!=[] and height[i]>height[st[-1]]: - midh = height[st[-1]] - st.pop() - if st!=[]: - hright = height[i] - hleft = height[st[-1]] - h = min(hright,hleft)-midh - w = i-st[-1]-1 - result+=h*w - st.append(i) + for i in range(1, len(height)): + # 情况一 + if height[i] < height[stack[-1]]: + stack.append(i) + + # 情况二 + # 当当前柱子高度和栈顶一致时,左边的一个是不可能存放雨水的,所以保留右侧新柱子 + # 需要使用最右边的柱子来计算宽度 + elif height[i] == height[stack[-1]]: + stack.pop() + stack.append(i) + + # 情况三 + else: + # 抛出所有较低的柱子 + while stack and height[i] > height[stack[-1]]: + # 栈顶就是中间的柱子:储水槽,就是凹槽的地步 + mid_height = height[stack[-1]] + stack.pop() + if stack: + right_height = height[i] + left_height = height[stack[-1]] + # 两侧的较矮一方的高度 - 凹槽底部高度 + h = min(right_height, left_height) - mid_height + # 凹槽右侧下标 - 凹槽左侧下标 - 1: 只求中间宽度 + w = i - stack[-1] - 1 + # 体积:高乘宽 + result += h * w + stack.append(i) return result + +# 单调栈压缩版 +class Solution: + def trap(self, height: List[int]) -> int: + stack = [0] + result = 0 + for i in range(1, len(height)): + while stack and height[i] > height[stack[-1]]: + mid_height = stack.pop() + if stack: + # 雨水高度是 min(凹槽左侧高度, 凹槽右侧高度) - 凹槽底部高度 + h = min(height[stack[-1]], height[i]) - height[mid_height] + # 雨水宽度是 凹槽右侧的下标 - 凹槽左侧的下标 - 1 + w = i - stack[-1] - 1 + # 累计总雨水体积 + result += h * w + stack.append(i) + return result + ``` Go: