代码随想录27期|Python|Day53|​单调栈|​739. 每日温度|​496. 下一个更大元素 I|​​496. 下一个更大元素 I​

本章开始单调栈的内容。

739. 每日温度

本题翻译过来就是:找每一个元素从这个下标开始,第一个比他大的元素的下标,返回二者之间的距离。

单调栈的工作原理:

单调栈的本质是空间换时间,因为在遍历的过程中需要用一个栈来记录右边第一个比当前元素高的元素,优点是整个数组只需要遍历一次。

由于我们要求的是右侧第一个递增的元素,所以要维护一个从底部到顶部为递增到栈。

同时为了记录距离,需要同时伴随一个记录答案的数组。

1、比较栈顶下标所指向的元素和遍历到的元素大小,如果比遍历到的元素大,则将遍历到的元素放入栈中

2、如果栈顶元素和遍历到的元素相等,则也将元素放入栈中

            stack.append(i)  # 新元素的下标加入栈顶

3、如果栈顶元素小于遍历到的元素,则将两者索引的差值储存到结果集合中对应的栈顶元素的下标位置,同时弹出栈顶元素重复以上过程,直到遍历到的元素比栈顶元素小,将遍历到的元素加入栈顶。

while stack and temperatures[i] > temperatures[stack[-1]]:  # 当栈非空,并且当前栈顶下标所对应的气温小于当前遍历的气温
                res[stack[-1]] = i - stack[-1]  # 储存结果
                stack.pop()  # 弹出栈顶元素
class Solution(object):
    def dailyTemperatures(self, temperatures):
        """
        :type temperatures: List[int]
        :rtype: List[int]
        """
        res = [0] * len(temperatures)  # 存放结果
        stack = []  # 存放下标
        for i in range(len(temperatures)):
            while stack and temperatures[i] > temperatures[stack[-1]]:  # 当栈非空,并且当前栈顶下标所对应的气温小于当前遍历的气温
                res[stack[-1]] = i - stack[-1]  # 储存结果
                stack.pop()  # 弹出栈顶元素
            stack.append(i)  # 新元素的下标加入栈顶
        return res

496. 下一个更大元素 I

本题和上一个题目的区别在于需要在储存答案之前判断是否出现在另一个数组中,并且还需要查找出现的索引位置。

因为1是2的子集,所以在遍历的过程中,以2作为主要的遍历对象,同时在2中维护一个单调栈在栈顶元素和1中一致的时候查询这个元素在1中的位置,同时更新答案对应索引位置处的值为新遍历到的元素。

代码相当于在上一题的基础上加入了判断和取索引的过程。

class Solution(object):
    def nextGreaterElement(self, nums1, nums2):
        """
        :type nums1: List[int]
        :type nums2: List[int]
        :rtype: List[int]
        """
        res = [-1] * len(nums1)
        stack = []

        for i in range(len(nums2)):
            while stack and nums2[i] > nums2[stack[-1]]:
                if nums2[stack[-1]] in nums1:  # 只有当nums2的元素出现在nums1中时,才会记录到res中,否则只是在nums2中维护一个单调栈
                    index1 = nums1.index(nums2[stack[-1]])
                    res[index1] = nums2[i]
                stack.pop()
            stack.append(i)
        return res

503. 下一个更大元素 II

 本题在温度的替代基础上加入了循环的要求,也就是数组的首尾相接。

为了不单独增加内存,这里不将nums进行扩充成2倍,而是采用模拟走两遍的方法进行遍历。

也就是遍历的index在range(len(nums) * 2),那么如何将index映射回对应在数组里的实际下标呢?

对len(nums)取余数即可,例如,在遍历到len(nums) + 1的时候,也就是实际上映射到了原来是数组的下标1处。

所以这里的index不是指实际上的数组下标,应该在单调栈维护的过程中使用[i % len(nums)]作为实际的下标

class Solution(object):
    def nextGreaterElements(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        res = [-1] * len(nums)
        stack = []
        for i in range(len(nums) * 2):
            while stack and nums[i % len(nums)] > nums[stack[-1]]:
                res[stack[-1]] = nums[i % len(nums)]
                stack.pop()
            stack.append(i % len(nums))
        return res

Day53完结!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值