一、739. 每日温度
题目链接:739. 每日温度 - 力扣(LeetCode)
文章讲解:代码随想录 (programmercarl.com)——739. 每日温度
视频讲解:单调栈,你该了解的,这里都讲了!LeetCode:739.每日温度_哔哩哔哩_bilibili
单调栈作用:存放之前遍历过的元素,适合求当前元素左边或右边第一个比其大或小的元素。
单调栈递增:求前后第一个比其大的元素
单调栈递减:求前后第一个比其小的元素
单调栈三个判断条件:
1. 当前遍历的元素 T[ i ] < 栈顶元素 T[st.top()] 的情况
2. 当前遍历的元素 T[ i ] = 栈顶元素 T[st.top()] 的情况
3. 当前遍历的元素 T[ i ] > 栈顶元素 T[st.top()] 的情况
class Solution:
def dailyTemperatures(self, temperatures: List[int]) -> List[int]:
# 定义一个栈,存储温度下标,而不是温度值
stack = [0]
# 定义一个结果数组
result = [0] * len(temperatures)
for i in range(1, len(temperatures)):
# 当前遍历元素 < 栈口元素,直接把下标加入栈中
if temperatures[i] < temperatures[stack[-1]]:
stack.append(i)
# 当前遍历元素 = 栈口元素,依然加入栈中
elif temperatures[i] == temperatures[stack[-1]]:
stack.append(i)
# 当前遍历元素 > 栈口元素,一直进行比较,并将栈中元素弹出,记录结果,注意需要判断栈不为空
else:
while len(stack) != 0 and temperatures[i] > temperatures[stack[-1]]:
result[stack[-1]] = i - stack[-1]
stack.pop()
stack.append(i)
return result
二、496.下一个更大元素 I
题目链接:496. 下一个更大元素 I - 力扣(LeetCode)
文章讲解:代码随想录 (programmercarl.com)——496.下一个更大元素 I
视频讲解:单调栈,套上一个壳子就有点绕了| LeetCode:496.下一个更大元素_哔哩哔哩_bilibili
思路:定义一个和 nums1 大小一样且全为 -1 的 result 数组,在 nums2 中找nums1 对应元素的位置,用单调递增栈
class Solution:
def nextGreaterElement(self, nums1: List[int], nums2: List[int]) -> List[int]:
# 定义一个栈
stack = [0]
# 定义一个结果数组
result = [-1] * len(nums1)
# 如果 nums1 为空,直接输出结果
if len(nums1) == 0:
return result
# 开始遍历nums2
for i in range(1, len(nums2)):
# 当前遍历元素 < 栈口元素,直接把下标加入栈中
if nums2[i] < nums2[stack[-1]]:
stack.append(i)
# 当前遍历元素 = 栈口元素,依然加入栈中
elif nums2[i] == nums2[stack[-1]]:
stack.append(i)
# 当前遍历元素 > 栈口元素,一直进行比较,并将栈中元素弹出,记录结果,注意需要判断栈不为空
else:
while len(stack) != 0 and nums2[i] > nums2[stack[-1]]:
# 判断栈顶元素是否在nums1中出现过
if nums2[stack[-1]] in nums1:
# 获取nums1中对应下标
index = nums1.index(nums2[stack[-1]])
# 在下标位置更新结果中的位置,结果为当前遍历元素
result[index] = nums2[i]
stack.pop()
stack.append(i)
return result
三、503.下一个更大元素II
题目链接:503. 下一个更大元素 II - 力扣(LeetCode)
文章讲解:代码随想录 (programmercarl.com)——503.下一个更大元素II
视频讲解:单调栈,成环了可怎么办?LeetCode:503.下一个更大元素II_哔哩哔哩_bilibili
思路1:将两个相同的 nums 拼接成一个新数组 new_nums,在新数组上进行操作。
思路2:取模的方式模拟成环操作,按2倍数组长度遍历,i 取模,当超过数组长度时,余数又重新回到数组中
for i in range(len(nums) * 2):
索引为 i % len(nums)
class Solution:
def nextGreaterElements(self, nums: List[int]) -> List[int]:
# 创建一个单调栈
stack = [0]
# 创建全为 -1 的结果数组
result = [-1] * len(nums)
# 如果 nums 为空,直接输出结果
if len(nums) == 0:
return result
for i in range(1, len(nums) * 2):
# 当前遍历元素 < 栈口元素,直接把下标加入栈中
if nums[i%len(nums)] < nums[stack[-1]]:
stack.append(i%len(nums))
# 当前遍历元素 = 栈口元素,依然加入栈中
elif nums[i%len(nums)] == nums[stack[-1]]:
stack.append(i%len(nums))
# 当前遍历元素 > 栈口元素,一直进行比较,并将栈中元素弹出,记录结果,注意需要判断栈不为空
else:
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