第十章 单调栈 Part1

任务

739. 每日温度

给定一个整数数组 temperatures ,表示每天的温度,返回一个数组 answer ,其中 answer[i] 是指对于第 i 天,下一个更高温度出现在几天后。如果气温在这之后都不会升高,请在该位置用 0 来代替。

思路

使用单调栈来解决这种类型的问题(右边第一个比我大(小)的值)
需要注意的点为,栈中存放的是索引,比较时比较的是值,容易粗心出错。注意将处理完的栈顶节点弹出,以及处理完一轮弹出循环后,需要将当前这个比较节点加入到栈中,最后这个比较容易遗漏。这里是根据题意收集结果后弹出,实际上即使不收集结果或者是在特殊条件下收集结果,弹出的流程也是根据单调栈的处理流程来的(维护单调栈本身的结构),而不是收集结果后直接弹出的,这点需要注意,即只要满足 len(stack) > 0 and temperatures[i] > temperatures[stack[-1]] 条件就弹出,可以参考下一题。

class Solution:
def dailyTemperatures(self, temperatures: List[int]) -> List[int]:
stack = []
result = [0] * len(temperatures)
for i in range(len(temperatures)):
if len(stack) > 0 and 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

另外,上面的代码可以简化,但是为了逻辑的清晰,后续单调栈的题还是先按照上面的相对麻烦的写法来。

class Solution:
def dailyTemperatures(self, temperatures: List[int]) -> List[int]:
stack = []
result = [0] * len(temperatures)
for i in range(len(temperatures)):
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

nums1 中数字 x 的 下一个更大元素 是指 x 在 nums2 中对应位置 右侧 的 第一个 比 x 大的元素。

给你两个 没有重复元素 的数组 nums1 和 nums2 ,下标从 0 开始计数,其中nums1 是 nums2 的子集。

对于每个 0 <= i < nums1.length ,找出满足 nums1[i] == nums2[j] 的下标 j ,并且在 nums2 确定 nums2[j] 的 下一个更大元素 。如果不存在下一个更大元素,那么本次查询的答案是 -1 。

返回一个长度为 nums1.length 的数组 ans 作为答案,满足 ans[i] 是如上所述的 下一个更大元素 。

思路

实际就是上一题的变形,只要理解了单调栈的本体逻辑,这题是在特殊情况下收集结果,而为了维持单调栈本身的结构和流程,需要注意弹出的时机。

class Solution:
def nextGreaterElement(self, nums1: List[int], nums2: List[int]) -> List[int]:
stack = []
result = [-1] * len(nums1)
for i in range(len(nums2)):
if len(stack)>0 and nums2[i] <= nums2[stack[-1]]:
stack.append(i)
else:
while len(stack) > 0 and nums2[i] > nums2[stack[-1]]:
if nums2[stack[-1]] in nums1:
result[nums1.index(nums2[stack[-1]])] = nums2[i]
stack.pop()
stack.append(i)
return result

503. 下一个更大元素 II

给定一个循环数组 nums ( nums[nums.length - 1] 的下一个元素是 nums[0] ),返回 nums 中每个元素的 下一个更大元素 。

数字 x 的 下一个更大的元素 是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你应该循环地搜索它的下一个更大的数。如果不存在,则输出 -1 。

思路

这题看似比较简单,将之前的普通数组改为了循环数组,会直接想到用取模。但实际上深入思考后,发现之所以result[i]没有被后续覆盖的,是因为后续(第二轮)不会进入到给result[i]赋值的条件内。
这道题的理解起来简单的思路是复制一份扩展为2倍的数组,这是完全符合题意的,但是编码还是用取模比较简洁和省空间。

class Solution:
def nextGreaterElements(self, nums: List[int]) -> List[int]:
stack = []
result = [-1] * len(nums)
for i in range(2 * len(nums)):
reali = i % len(nums)
if len(stack) > 0 and nums[reali] <= nums[stack[-1]]:
stack.append(reali)
else:
while len(stack) > 0 and nums[reali] > nums[stack[-1]]:
result[stack[-1]] = nums[reali]
stack.pop()
stack.append(reali)
return result
posted @   haohaoscnblogs  阅读(5)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示