代码随想录算法训练营day47| 739. 每日温度 496.下一个更大元素 I 503.下一个更大元素II

学习资料:https://programmercarl.com/0739.每日温度.html#算法公开课

单调栈:
用数组模拟单调栈,今天的题中,栈中元素都保存的索引值
基本思路:将新元素和栈顶索引对应值比较,如果要保持单调递增,则需要新元素不大于栈顶索引对应值;若满足就加入新元素索引到栈中;若不满足,就根据具体题意看是否找到目标值了,然后通过循环不断弹出栈顶值,知道新元素不大于栈顶值了,就把新元素索引加到栈中
循环数组:
当遇到循环数组问题,可以取模法:索引范围*2,再对每个索引取模 i%len(nums)

学习记录:
739.每日温度(单调栈;单调递增)

点击查看代码
class Solution(object):
    def dailyTemperatures(self, temperatures):
        """
        :type temperatures: List[int]
        :rtype: List[int]
        """
        # 单调栈解法,本题设定为递增,栈顶到栈底值越来越大(难点:栈中存放的是数的索引)

        # 先初始化结果数组,默认没有更高温度的出现
        answer = [0]*len(temperatures)    # 当后面几天没有更高温度时也不用处理了,因为本来初值就定为0了
        # 构建一个单调栈,还是数组的形式
        stack = [0]
        # 开始遍历温度
        for i in range(1, len(temperatures)):
            if temperatures[i] <= temperatures[stack[-1]]:   # 新元素的值<栈顶值,符合单调递增,加入栈
                stack.append(i)
            else:
                while len(stack) != 0 and temperatures[i] > temperatures[stack[-1]]:
                    # 记录结果
                    answer[stack[-1]] = i-stack[-1]
                    # 弹出栈顶值,因为这天的更高温度已经找到,如果还满足循环添加,则还要继续弹出
                    stack.pop()
                # 当栈顶对应值不再小于新元素时,加入新元素
                stack.append(i)
        return answer
        

496.下一个更大元素1(单调栈变形;当新元素大于栈顶索引对应值时,还得判断栈顶索引对应值是否是nums1中的元素,如果是,则找到目标值,即nums1在nums2中的更大值即为新元素)

点击查看代码
class Solution(object):
    def nextGreaterElement(self, nums1, nums2):
        """
        :type nums1: List[int]
        :type nums2: List[int]
        :rtype: List[int]
        """
        # 单调栈,特别之处:如果nums2的栈顶值<nums2遍历到的当前值,再判断栈顶值在不在nums1里面,如果在,就说明找到了nums1中数字的在nums2中的下一个更大元素
        # 构造单调栈
        stack = [0]   # 栈中保存的是索引!!!!!!!!!!!!!
        # 结果的保存,初值都设置为-1
        ans = [-1]*len(nums1)
        # 遍历nums2
        for i in range(1, len(nums2)):
            if nums2[stack[-1]] >= nums2[i]:
                stack.append(i)
            else:
                while len(stack) != 0 and nums2[stack[-1]]<nums2[i]:    # 防止空栈;当新元素大于栈顶元素
                    # 看栈顶元素是否在nums1中,如果在,就说明找到了nums1对应元素的下一个更大值,也就是新元素
                    if nums2[stack[-1]] in nums1:
                        # 保存结果
                        index = nums1.index(nums2[stack[-1]])
                        ans[index] = nums2[i]
                    # 不管怎样都要弹出栈顶,保证单调递增
                    stack.pop()
                # 当新元素不大于栈顶值时,向单调栈加入新元素
                stack.append(i)
        return ans

503.下一个更大元素2(单调栈+循环数组)

点击查看代码
class Solution(object):
    def nextGreaterElements(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        # 单调栈+环形数组问题
        # 当遇到环形数组,
            # 法一:扩展数组为其二倍,如[2,3,4]变成[2,3,4,2,3,4]
            # 法二: 索引取模法,for i in range(len(nums)*2): 后续中用i%len(nums),这样保证索引值一直是0,1,2
        
        # 构建单调栈,保存索引值
        stack = [0]
        # 构建结果数组
        result = [-1]*len(nums)
        # 开始2倍遍历
        for i in range(len(nums)*2):
            # 对索引取模
            i_mod = i%len(nums)
            # 新元素不大于栈顶值,满足单调递增
            if nums[i_mod] <= nums[stack[-1]]:
                stack.append(i_mod)    # 记住栈中保存的是索引
            else:
                # 开始循环,一直到新元素不大于栈顶值位置
                while len(stack) != 0 and nums[i_mod] > nums[stack[-1]]:
                    # 收集结果
                    result[stack[-1]] = nums[i_mod]   # 栈顶值的下一个更大元素是nums[i_mod]
                    # 弹出当前已经收集了结果的栈顶值
                    stack.pop()
                # 加入新元素
                stack.append(i_mod)
        return result
        

PS:今天阴转小雨,不冷;周五吃的很随意,排骨面,自选菜,味道都一般,但是吃得饱;很累啊,论文有了新进展,理清了行文思路;
这周没有找工作进展,是等待的一周,希望下周等到机会~

posted @ 2024-11-15 21:14  Tristan241001  阅读(20)  评论(0)    收藏  举报