● 503.下一个更大元素II ● 42. 接雨水
503.下一个更大元素II
在遍历的过程中模拟走了两边nums。
class Solution:
def nextGreaterElements(self, nums: List[int]) -> List[int]:
result = [-1] * len(nums)
stack = []
for i in range(2*len(nums)):
while(len(stack) != 0 and nums[i%len(nums)] > nums[stack[-1]]):
result[stack[-1]] = nums[i % len(nums)]
stack.pop()
stack.append(i%len(nums))
return result
42. 接雨水
双指针,会超时
class Solution:
def trap(self, height: List[int]) -> int:
# 双指针
res = 0
for i in range(len(height)):
if i == 0 or i == len(height)-1: continue
lHight = height[i-1]
rHight = height[i+1]
for j in range(i-1):
if height[j] > lHight:
lHight = height[j]
for k in range(i+2,len(height)):
if height[k] > rHight:
rHight = height[k]
res1 = min(lHight,rHight) - height[i]
if res1 > 0:
res += res1
return res
动态规划
class Solution:
def trap(self, height: List[int]) -> int:
# 动态规划
left_height = [0] * len(height)
right_height = [0] * len(height)
left_height[0] = height[0]
# 记录每个柱子左边柱子最大高度
for i in range(1, len(height)):
left_height[i] = max(left_height[i-1], height[i])
right_height[-1] = height[-1]
# 记录每个柱子右边柱子最大高度
for j in range(len(height)-2, -1, -1):
right_height[j] = max(right_height[j+1], height[j])
result = 0
for k in range(len(height)):
sum_val = min(left_height[k], right_height[k])-height[k]
result += sum_val
return result
单调栈
class Solution:
def trap(self, height: List[int]) -> int:
# 单调栈
# 单调栈
'''
单调栈是按照 行 的方向来计算雨水
从栈顶到栈底的顺序:从小到大
通过三个元素来接水:栈顶,栈顶的下一个元素,以及即将入栈的元素
雨水高度是 min(凹槽左边高度, 凹槽右边高度) - 凹槽底部高度
雨水的宽度是 凹槽右边的下标 - 凹槽左边的下标 - 1(因为只求中间宽度)
'''
# stack储存index,用于计算对应的柱子高度
stack = [0]
result = 0
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