1.题:给定 n
个非负整数表示每个宽度为 1
的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。42. 接雨水 - 力扣(LeetCode) (leetcode-cn.com)
- # #法一 动态规划
用动态规划的方法提前得到 每个位置两边的最大高度leftMax[i] 和 rightMax[i]
对于0≤i<n, 下标i处能接的雨水量=min(leftMax[i],rightMax[i])−height[i].
class Solution:
def trap(self, height: List[int]) -> int:
n=len(height)
leftmax,rightmax=[height[0]]+[0]*(n-1),[0]*(n-1)+[height[n-1]]
res=0
for i in range(1,n):
leftmax[i]=max(leftmax[i-1],height[i])
for i in range(n-2,-1,-1):
rightmax[i]=max(rightmax[i+1],height[i])
for i in range(n):
res+=min(leftmax[i],rightmax[i])-height[i]
return res
- #法二 双指针 降低空间复杂度 用双指针和两个变量代替两个数组
class Solution:
def trap(self, height: List[int]) -> int:
left,right=0,len(height)-1
leftmax,rightmax,res=0,0,0
while left<right:
leftmax=max(leftmax,height[left])
rightmax=max(rightmax,height[right])
if height[left]<height[right]:#必有leftMax<rightMax
res+=leftmax-height[left]#下标left 处能接的雨水量
left+=1
else:#必有leftMax>=rightMax
res+=rightmax-height[right]#下标right处能接的雨水量
right-=1
return res
- #法三 单调栈 存储下标,满足从栈底(左)到栈顶(右)的下标对应的数组height 中的元素递减。
class Solution:
def trap(self, height: List[int]) -> int:
n=len(height)
res,stack=0,[]
for i in range(n):
while stack and height[i]>height[stack[-1]]:
top=stack.pop(-1)#去调比height[i]小的height[stack[-1]]
if not stack:
break
left = stack[-1]# 栈顶元素为top,top的下面一个元素是left
width=i-left-1
high=min(height[left],height[i]) -height[top]
res+=high*width
stack.append(i)
return res
2.题:给定一个数组height,长度为n,每个数代表坐标轴中的一个点的高度,height[i]是在第i点的高度,请问,从中选2个高度与x轴组成的容器最多能容纳多少水。
- 以双指针为左右边界
求出当前双指针对应的容器的容量;
左右指针移动:对应数字较小的那个指针以后不可能作为容器的边界,将其丢弃,并移动对应的指针。
#把握:在移动的过程中不断消去不可能成为最大值的状态
class Solution:
def maxArea(self , height: List[int]) -> int:
left,right,res=0,len(height)-1,0
while left<right:
l=min(height[left],height[right])
res=max(res,l*(right-left))
if height[left]<height[right]:#移动指向值较小的指针
left+=1
else:
right-=1
return res