·题目描述
给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
示例 1:
输入:height = [0,1,0,2,1,0,1,3,2,1,2,1]
输出:6
解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。
示例 2:
输入:height = [4,2,0,3,2,5]
输出:9
·解题思路
——————动态规划————
1.从左到右遍历数组,记录最大值leftmax。每一个位置的eftmax都由前一个位置的leftmax和该位置的实际高度的最大值决定
2.同样的道理,从右到左遍历数组,记录rightmax。由于顺序变化了,所以每一个位置的rightmax都是由后一个位置的rightmax和该位置的height决定
3.再次遍历数组,每一个位置的装水量就是 leftmax和rightmax的最小值 载减去原位置的height
(从图解上确实如此,应该属于从左到右扫,再从右到左扫,取出共同的空白位置,就是装水量)
——————动态规划涉及两个新数组,对此利用双指针改进——————
1.用leftmax 数值记录每次遍历的左边的最大值(其比较就是动态规划记录的值)
2.同样的道理rightmax记录从右遍历的右边最大值
3.移动条件,左右两边谁的数值小谁就移动
4.在移动的时候,由于指针式动态的,所以需要每次记录当前位置可以装的水量
leftmax - height[left] or rightmax - height[right
(因为每次移动一步,所以width 为1)
——————单调栈————
1.每个元素可以转的水量,就是该元素和右边第一个大于该元素的位置所组成的凹槽
2.因此使用栈,在遍历的时候记录元素。如果右边元素小于该元素,继续入栈。反之则弹出,并且计算面积。
3.面积计算 Height= min(height[index] , height[left]) - height[top]
width = index - left -1
·代码
class Solution(object):
def trap(self,height:list[int])->int:
##单调栈
stack = list()
area = 0
for index,item in enumerate(height):
while stack and item > height[stack[-1]]:
top = stack.pop()
if not stack :
break
left = stack[-1]
width = index - left - 1
tall = min(height[index],height[left]) - height[top]
cur_area = width * tall
area += cur_area
stack.append(index)
return area
def trap1(self,height:list[int])->int:
##动态规划
n = len(height)
area = 0
left_max = [height[0]] + [0] * (n-1)
for i in range(1,n):
left_max[i] = max(left_max[i-1],height[i])
right_max = [0]*(n-1) + [height[n-1]]
for i in range(n-2, -1,-1):
right_max[i] = max(right_max[i+1],height[i])
for i in range(n):
area += min(left_max[i],right_max[i]) - height[i]
return area
def trap2(self,height :list[int]) ->int:
##双指针代替双数组
n = len(height)
left , right = 0, n - 1
area = 0
left_max , right_max = 0,0
while left < right:
left_max = max(left_max,height[left])
right_max = max(right_max,height[right])
if height[left] < height[right]:
area += left_max - height[left]
left += 1
else:
area += right_max - height[right]
right -= 1
return area
if __name__ == '__main__':
solution = Solution()
height = [5,4,1,2,5]
area = solution.trap2(height)
print(area)