主要内容
单调栈
单调栈题目
503. 下一个更大元素 II
代码
拼接,浪费空间,时间
class Solution:
def nextGreaterElements(self, nums: List[int]) -> List[int]:
n = len(nums)
newnums = nums + nums
stack = []
res = [-1] * (2 * n)
for i in range(2*n):
# 弹出
while stack and newnums[i] > newnums[stack[-1]]:
index = stack.pop()
res[index] = newnums[i]
stack.append(i)
return res[:n]
class Solution:
def nextGreaterElements(self, nums: List[int]) -> List[int]:
n = len(nums)
res = [-1] * n
stack = []
for i in range(2 * n):
# 弹出,记录
while stack and nums[i % n] > nums[stack[-1]]:
index = stack.pop()
res[index] = nums[i % n]
# 加入
stack.append(i % n)
return res
42. 接雨水
思路分析
- 双指针:超时了 (计算雨水高)
- 动态规划:优化计算左右最高 (计算雨水高)
- 单调栈:形成凹槽(计算雨水行)
代码
class Solution:
# 双指针方法,计算雨水高, 超时了
# 对于当前高度,找到其左边最高的柱子lefth,右边最高的柱子righth,
# 则当前柱子上的雨水高度为 min(lefth, righth) - height[i]
def trap(self, height: List[int]) -> int:
res = 0
n = len(height)
for i in range(1, n - 1):
lefth = height[i-1]
righth = height[i+1]
# 向左找最高
for j in range(i-1):
lefth = max(lefth, height[j])
# 向右找最高
for j in range(i+2, n):
righth = max(righth, height[j])
h = min(lefth, righth) - height[i]
if h > 0:
res += h
return res
class Solution:
# 采用动态规划,优化左右最高柱子的计算
# 对于当前高度,找到其左边最高的柱子lefth,右边最高的柱子righth,
# 则当前柱子上的雨水高度为 min(lefth, righth) - height[i]
def trap(self, height: List[int]) -> int:
n = len(height)
lefth = [-1] * n
righth = [-1] * n
# 左侧最高
lefth[0] = height[0]
for i in range(1, n):
lefth[i] = max(lefth[i-1], height[i])
# 右侧最高
righth[n-1] = height[n-1]
for i in range(n-2, -1, -1):
righth[i] = max(righth[i+1], height[i])
res = 0
for i in range(1, n - 1):
h = min(lefth[i], righth[i]) - height[i]
if h > 0:
res += h
return res
class Solution:
# 采用单调栈,计算凹槽内的雨水
# 单调栈内从底到头是递减的,
# 1. 当前元素小于栈头,直接加入
# 2. 当前元素等于栈头,替换栈头
# 3. 当前元素大于栈头,形成凹槽,计算
def trap(self, height: List[int]) -> int:
res = 0
n = len(height)
stack = []
stack.append(0)
for i in range(1, n):
# print("i:",i)
# print("pre stack:",stack)
# print("pre res:",res)
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 = stack.pop()
if stack:
h = min(height[stack[-1]], height[i]) - height[mid]
w = i - stack[-1] - 1
res += h * w
stack.append(i)
# print("now stack:",stack)
# print("now res:",res)
return res
class Solution:
# 采用单调栈,计算凹槽内的雨水
# 单调栈内从底到头是递减的,
# 1. 当前元素小于栈头,直接加入
# 2. 当前元素等于栈头,替换栈头
# 3. 当前元素大于栈头,形成凹槽,计算
def trap(self, height: List[int]) -> int:
res = 0
n = len(height)
stack = []
stack.append(0)
for i in range(1, n):
# print("i:",i)
# print("pre stack:",stack)
# print("pre res:",res)
while stack and height[i] > height[stack[-1]]:
mid = stack.pop()
if stack:
h = min(height[stack[-1]], height[i]) - height[mid]
w = i - stack[-1] - 1
res += h * w
stack.append(i)
# print("now stack:",stack)
# print("now res:",res)
return res