503.下一个更大元素II
1.题目
给定一个循环数组(最后一个元素的下一个元素是数组的第一个元素),输出每个元素的下一个更大元素。数字 x 的下一个更大的元素是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你应该循环地搜索它的下一个更大的数。如果不存在,则输出 -1。
2.实现
循环遍历,建议不要延长数组,只需延长遍历长度,通过取余来取值
class Solution:
def nextGreaterElements(self, nums: List[int]) -> List[int]:
# 无需延长数组,只需延长遍历长度再取余即可
nums.extend(nums)
n = len(nums)
stack = []
res = [-1] * int(n / 2)
for i in range(n):
while stack and nums[stack[-1]] < nums[i]:
index = stack.pop()
index = index % (n // 2)
if res[index] == -1:
res[index] = nums[i]
stack.append(i)
return res
42. 接雨水
1.题目
给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
2.实现
思路:从行和列两个方向来求解,重点是如何计算雨水的面积
class Solution:
def trap(self, height: List[int]) -> int:
# 用dp方法记录每个柱子的 左最高 和 右最高
# n = len(height)
# if n < 3: return 0
# lheight, rheight = [0] * n, [0] * n
# lheight[0], rheight[n - 1] = height[0], height[n - 1]
# for i in range(1, n):
# lheight[i] = max(height[i], lheight[i - 1])
# for j in range(n - 2, -1, -1):
# rheight[j] = max(height[j], rheight[j + 1])
# res = 0
# for i in range(1, n - 1):
# res += (min(lheight[i], rheight[i]) - height[i])
# return res
# 用单调栈的方法
n = len(height)
stack = []
res = 0
for i in range(n):
if stack and height[stack[-1]] == height[i]:
stack.pop()
elif stack and height[stack[-1]] < height[i]:
while stack and height[stack[-1]] < height[i]:
index = stack.pop()
if stack:
h = min(height[i], height[stack[-1]]) - height[index]
w = i - stack[-1] - 1
# print(res)
res += (h * w)
stack.append(i)
return res
小结:
单调栈的顺序 决定栈内元素记录的是 左右两边与他的大小关系 的类型
如该题:
栈内遵循:从栈头到栈底为递增顺序
则对于 1 来说,当更新栈内元素时,对于栈顶元素 1 来说,2 是左边第一个比他大的元素,3 是右边第一个比他大的元素;
如果顺序变为递减顺序,则得出相反结论。
拓展习题:
84. 柱状图中最大的矩形 要去二刷哦!
文章讲解