day48 单调栈1

124 阅读2分钟

739. 每日温度

文章讲解

思路:

单调栈,构建stack栈顶到栈顶从小到大,形如金字塔。然后新的数值只有比底下的都小才能放到栈顶,否则把比他小的都取出。
class Solution:
    def dailyTemperatures(self, temperatures: List[int]) -> List[int]:
        result = [0] * len(temperatures) # 答案数组
        stack = [0] # 记录元素索引 确保栈有元素
        for i in range(1, len(temperatures)):
            # 当前温度<=栈顶温度,直接加入
            if temperatures[i] <= temperatures[stack[-1]]:
                stack.append(i)
            else:
                # 栈不为空,且元素i>栈顶元素时,把比他小的都取出来  
                while stack and temperatures[i] > temperatures[stack[-1]]:
                    # 更新答案
                    result[stack[-1]] = i - stack[-1] # 弹出来的元素索引为stack[-1],元素i是第一个比他大的元素,间距为i-stack[-1]
                    stack.pop()
                stack.append(i)
        return result

496. 下一个更大元素 I

文章讲解

思路:

思路:使用单调栈找到每一个元素的下一个最大的元素,然后判断当前元素是否在nums1里,然后更新答案
class Solution:
    def nextGreaterElement(self, nums1: List[int], nums2: List[int]) -> List[int]:
        # 构建nums1元素到索引的映射
        num2idx = {}
        for i in range(len(nums1)):
            num2idx[nums1[i]] = i
        # 单调栈
        result = [-1] * len(nums1)
        stack = [0] # 记录元素索引,元素从栈顶到栈底递增
        for i in range(1, len(nums2)):
            # <= 栈顶,直接加入
            if nums2[i] <= nums2[stack[-1]]:
                stack.append(i)
            # >栈顶,弹出并更新结果
            else:
                while stack and nums2[i] > nums2[stack[-1]]:
                    # 如果当前弹出的元素在nums1里
                    num = nums2[stack[-1]]
                    if num in num2idx:
                        result[num2idx[num]]  = nums2[i] # 记录比他大的元素
                    stack.pop() # 忘了弹出了
                stack.append(i)
        return result

简化版本:

class Solution:
    def nextGreaterElement(self, nums1: List[int], nums2: List[int]) -> List[int]:
        # 构建nums1元素到索引的映射
        num2idx = {num: i for i, num in enumerate(nums1)}
        # 单调栈
        result = [-1] * len(nums1)
        stack = []  # 记录元素索引,元素从栈顶到栈底递增

        for i in range(len(nums2)):
            # 处理栈中的元素
            while stack and nums2[i] > nums2[stack[-1]]:
                num = nums2[stack.pop()]
                if num in num2idx:
                    result[num2idx[num]] = nums2[i]  # 记录比他大的元素
            # 将当前元素的索引压入栈中
            stack.append(i)

        return result

503. 下一个更大元素 II

文章讲解

思路:

思路:单调栈,拼接两个nums,当前元素就用nums[i%len(nums)]

class Solution:
    def nextGreaterElements(self, nums: List[int]) -> List[int]:
        n = len(nums)
        result = [-1] * n
        stack = [0]
        for i in range(1, 2*n):
            # 把比当前元素小的栈元素全删除
            while stack and nums[i%n] > nums[stack[-1]]:
                # 更新答案
                result[stack[-1]] = nums[i%n]
                stack.pop()

            # 加入当前元素
            stack.append(i%n) # 注意不要越界
        return result