代码随想录算法训练营第51天

23 阅读2分钟

单调栈的使用场景

通常是一维数组,要寻找任一个元素的右边或者左边第一个比自己大或者小的元素的位置,此时我们就要想到可以用单调栈了
栈的作用是记录之前遍历过的元素
使用单调栈时要明确以下问题:

  • 单调栈中存放的元素是什么
  • 单调栈里的元素是递增还是递减

739. 每日温度

思路:比较temperature和以栈顶元素为下标的temperature的大小,如果temperature元素更大,那么需要对结果进行记录,并弹出栈顶元素。否则就把该下标添加到栈顶。

class Solution:
    def dailyTemperatures(self, temperatures: List[int]) -> List[int]:
        """
        暴力解法就是两次循环遍历,复杂度为o(n2)
        """
        n=len(temperatures)
        res=[0]*n
        s=[] #s是我们的栈
        for i in range(n-1,-1,-1): #倒着往栈里放
            while s and temperatures[s[-1]]<=temperatures[i]: #你是个矮个温度
                s.pop()
            res[i]=0 if not s else s[-1]-i
            s.append(i)
        return res

496.下一个更大元素Ⅰ

思路:先找到nums2数组,根据模板求出他的下一个最大值的列表。然后得出映射,再让nums1中的元素去查表,没有的赋成-1即可

class Solution:
    def nextGreaterElement(self, nums1: List[int], nums2: List[int]) -> List[int]:
        res=self.calculateGreatElement(nums2) #得到nums2下一个更大元素列表
        nums2map={}
        ans=[0]*len(nums1)
        for i in range(len(nums2)):
            nums2map[nums2[i]]=res[i]
        for i in range(len(nums1)):
            ans[i]=nums2map.get(nums1[i],-1)
        return ans

    def calculateGreatElement(self,nums2):
        n=len(nums2)
        res=[0]*n
        stack=[]
        for i in range(n-1,-1,-1):
            while stack and nums2[i]>=stack[-1]:
                stack.pop()
            res[i]=-1 if not stack else stack[-1]
            stack.append(nums2[i])
        return res

503.下一个更大元素

class Solution:
    def nextGreaterElements(self, nums: List[int]) -> List[int]:
        #我的想法:构造一个新的列表,让新列表等于两个源列表
        n=len(nums)
        new_nums=nums*2
        res=[-1]*n
        stack=[]
        for i in range(2*n-1,-1,-1):
            while stack and new_nums[i]>=stack[-1]:
                stack.pop()
            res[i%n]=-1 if not stack else stack[-1] #实际索引需要取模,因为我们只关心原数组的部分
            stack.append(nums[i%n])
        return res