首页 > 其他分享 >第十章 单调栈 Part1

第十章 单调栈 Part1

时间:2024-09-02 12:53:04浏览次数:10  
标签:nums 第十章 len nums1 Part1 单调 stack nums2 result

目录

任务

739. 每日温度

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

思路

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

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

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

标签:nums,第十章,len,nums1,Part1,单调,stack,nums2,result
From: https://www.cnblogs.com/haohaoscnblogs/p/18392504

相关文章

  • Study Plan For Algorithms - Part18
    1.搜索插入位置题目链接:https://leetcode.cn/problems/search-insert-position/给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。classSolution:defsearchInsert(self,nums:List[int],target:......
  • 第九章 动态规划Part13
    目录任务647.回文子串思路516.最长回文子序列思路任务647.回文子串给你一个字符串s,请你统计并返回这个字符串中回文子串的数目。回文字符串是正着读和倒过来读一样的字符串。子字符串是字符串中的由连续字符组成的一个序列。思路这道题的DP思路不是很直观,dp表示的......
  • 单调栈
    单调栈经典用法:在数组中当前元素的两侧找第一个比当前元素更大(更小)的数在哪维持求解答案的可能性单调栈里的所有对象按照规定好的单调性来组织当某个对象进入单调栈时,会从栈顶开始依次淘汰单调栈里对后续求解答案没有帮助的对象每个对象从栈顶弹出时结算当前对象参......
  • 738. 单调递增的数字(leetcode)
    https://leetcode.cn/problems/monotone-increasing-digits/description/classSolution{publicintmonotoneIncreasingDigits(intn){//返回单调递增的最大数字//思路比较巧妙的贪心题,需要仔细考虑两个相邻位之间的比较//一旦发现有前一......
  • Study Plan For Algorithms - Part16
    1.下一个排列题目链接:https://leetcode.cn/problems/next-permutation/整数数组的一个排列就是将其所有成员以序列或线性顺序排列。整数数组的下一个排列是指其整数的下一个字典序更大的排列。更正式地,如果数组的所有排列根据其字典顺序从小到大排列在一个容器中,那么数组......
  • 第九章 动态规划Part12
    目录任务115.不同的子序列思路583.两个字符串的删除操作思路72.编辑距离思路任务115.不同的子序列给你两个字符串s和t,统计并返回在s的子序列中t出现的个数,结果需要对10^9+7取模。思路dp[i][j]表示s[0:i)中出现以t[0,j)的次数每次拓展一个字符,求次数,直到拓......
  • 第九章 动态规划Part11
    目录任务1143.最长公共子序列思路1035.不相交的线思路53.最大子数组和思路392.判断子序列思路任务1143.最长公共子序列给定两个字符串text1和text2,返回这两个字符串的最长公共子序列的长度。如果不存在公共子序列,返回0。一个字符串的子序列是指这样一个新的字......
  • 第九章 动态规划Part10
    目录任务300.最长递增子序列思路674.最长连续递增序列思路718.最长重复子数组思路任务300.最长递增子序列子序列是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7]是数组[0,3,1,6,2,2,7]的子序列思路dp[i]表示以索引i结尾的最......
  • 单调队列--滑动窗口最大值(leetcode23)
    目录一、单调队列介绍二、题目应用1.题目描述2.解题碎碎念3.代码示例三、扩展1.与优先队列区别2.单调队列其他题目一、单调队列介绍单调队列是一种特殊的队列数据结构,它能够在常数时间内找到队列中的最值。单调队列可以用来解决一些与最值相关的问题,例如滑动窗口最......
  • P5788 【模板】单调栈
    P5788【模板】单调栈传送门题目描述给出项数为\(n\)的整数数列\(a_{1\dotsn}\)。定义函数\(f(i)\)代表数列中第\(i\)个元素之后第一个大于\(a_i\)的元素的下标,即\(f(i)=\min_{i<j\leqn,a_j>a_i}\{j\}\)。若不存在,则\(f(i)=0\)。试求出\(f(1\dotsn)\)。......