【LeetCode力扣】单调栈解决Next Greater Number(下一个更大值)问题

news2024/11/25 2:42:54

目录

1、题目介绍

2、解题思路

2.1、暴力破解法

2.2、经典Next Greater Number问题解法


1、题目介绍

原题链接:496. 下一个更大元素 I - 力扣(LeetCode)

示例1:

输入:nums1 = [4,1,2], nums2 = [1,3,4,2].
输出:[-1,3,-1]
解释:nums1 中每个值的下一个更大元素如下所述:
- 4 ,用加粗斜体标识,nums2 = [1,3,4,2]。不存在下一个更大元素,所以答案是 -1 。
- 1 ,用加粗斜体标识,nums2 = [1,3,4,2]。下一个更大元素是 3 。
- 2 ,用加粗斜体标识,nums2 = [1,3,4,2]。不存在下一个更大元素,所以答案是 -1 。

实例2:

输入:nums1 = [2,4], nums2 = [1,2,3,4].
输出:[3,-1]
解释:nums1 中每个值的下一个更大元素如下所述:
- 2 ,用加粗斜体标识,nums2 = [1,2,3,4]。下一个更大元素是 3 。
- 4 ,用加粗斜体标识,nums2 = [1,2,3,4]。不存在下一个更大元素,所以答案是 -1 。

提示:

  • 1 <= nums1.length <= nums2.length <= 1000
  • 0 <= nums1[i], nums2[i] <= 10^4
  • nums1和nums2中所有整数 互不相同
  • nums1 中的所有整数同样出现在 nums2 中

2、解题思路

        该题如果使用暴力破解法,其代码实现过程是很容易想到的,只需要找到nums1此时的元素在nums2中的位置,并向右查询是否存在更大的值,有则返回该值,无则返回-1即可。结合思想不难想到时间复杂度为O(m*n),m和n分别为两个数组各自的长度。虽然该题直接使用暴力破解法可以直接通过,但是只是出题人没有为难大家,如果该题的数据非常庞大,此时直接使用暴力破解法必然会导致超时。而本文将讲解单调队列的算法模版解决这类问题,它能够很好的将时间复杂度控制在O(m+n)。

下面将使用两种方法来解题,一种是暴力破解法,一种是Next Greater Number问题解法。

2.1、暴力破解法

从头开始遍历nums1,每次遍历从nums2中找到对应元素,然后从该元素的下一个元素开始依次比较,找出大于该值的第一个元素即可。

【代码实现】 

class Solution {
    public int[] nextGreaterElement(int[] nums1, int[] nums2) {
        int m = nums1.length, n = nums2.length;
        int[] res = new int[m];
        for (int i = 0; i < m; ++i) {
            int j = 0;
            while (j < n && nums2[j] != nums1[i]) {  //在nums2中找到该值
                ++j;
            }
            int k = j + 1;
            while (k < n && nums2[k] < nums2[j]) {   //从该值的下一个元素开始向右查找
                ++k;
            }
            res[i] = k < n ? nums2[k] : -1;    //超出nums2数组长度则表示不存在比该值大的数,返回-1
        }
        return res;
    }
}

时间复杂度:O(m*n),m和n分别为两数组的长度。

空间复杂度:O(1)。

2.2、经典Next Greater Number问题解法

首先需要补充一些知识点,下面用一个比较抽象的例子讲解:

把数组的元素想象成并列站立的人,元素大小想象成人的身高。视线从左往右,这些人面对你站成一列。如何求第一个元素【2】的下一个更大值呢?,其实很简单,只要没被该元素【2】挡住的第一个元素,就是【2】的下一个更大值,如下图所示,第一个【2】没有挡住的第一个元素就是【4】,此时【4】就是【2】的下一个更大值。

当理解了这个前提后,我们从后往前遍历该数组:

【3】,【3】背后看不到任何元素,即没有比它更大的右元素,因此next greater为-1;

【4】,【4】背后依然看不到任何元素(3被挡住了),此时next greater为-1;

【2】,【2】背后看到的第一个元素是4,因此next greater为4;(绿色2)

【1】,【1】背后看到的第一个元素是2,因此next greater为2;

【2】,【2】背后看到的第一个元素是4,因此next greater为4;(蓝色2)

在代码中为了记录某个值背后没被挡住的第一个元素,这里使用栈stack来记录,入栈出栈规则:当前值比栈中元素大时(证明被挡住了),将该值出栈,直至栈空或当前值小于栈顶元素,此时栈顶元素即为next greater;随后将当前值入栈。

因此我们需要做的就是从后往前遍历nums2数组,并计算出nums2对于的next greater,同时使用Map将【nums2的该值】以及【该值的next greater】记录下来,最后遍历nums1数组,从Map中取出对应值的next greater存入返回数组ret中即可。下面是代码实现部分。

【代码实现】 

class Solution {
    public int[] nextGreaterElement(int[] nums1, int[] nums2) {
        Stack<Integer> stack = new Stack<>();
        Map<Integer,Integer> map = new HashMap<>();
        for(int i = nums2.length - 1; i >= 0; i--) {   //从后往前
            int num = nums2[i];
            while(!stack.isEmpty() && stack.peek() <= num) {   //栈内元素小于等于当前值时,出栈
                stack.pop();       //让栈始终保持只有【大于】当前值的元素
            }
            map.put(num,stack.isEmpty() ? -1 : stack.peek());   //map记录该值的下一个最大值,没有则-1
            stack.push(num);
        }
        int[] ret = new int[nums1.length];
        for(int i = 0; i < nums1.length; i++) {    //将map中的对应值取出存入返回数组
            ret[i] = map.get(nums1[i]);
        }
        return ret;
    }
}

时间复杂度:O(m+n),m和n分别为两数组的长度。

空间复杂度:O(n),用于存储哈希表。

更多【LeetCode刷题】推荐:

【LeetCode力扣】面试题 17.14. 最小K个数(top-k问题)-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/zzzzzhxxx/article/details/135737266?spm=1001.2014.3001.5501 【LeetCode力扣】42. 接雨水-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/zzzzzhxxx/article/details/134104222?spm=1001.2014.3001.5501

 【LeetCode力扣】189 53 轮转数组 | 最大子数组和-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/zzzzzhxxx/article/details/134095703?spm=1001.2014.3001.5502

如果觉得作者写的不错,求给博主一个大大的点赞支持一下,你们的支持是我更新的最大动力!

如果觉得作者写的不错,求给博主一个大大的点赞支持一下,你们的支持是我更新的最大动力!

如果觉得作者写的不错,求给博主一个大大的点赞支持一下,你们的支持是我更新的最大动力!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1433901.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AMH面板如何安装与公网远程访问本地面板界面

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

html2Canvas截取百度地图问题整理及解决方案

目录 一、截图地图打点出不来二、截图报错Uncaught (in promise)html2Canvas属性大全 一、截图地图打点出不来 1.开启foreignObjectRendering 原因是地图打点中含有svg var canvas await html2canvas(obj, {useCORS: true, foreignObjectRendering: true})2.页面图片转base6…

Multi ElasticSearch Head插件基本操作

Multi ElasticSearch Head插件安装好之后我们可以进行一些基本的操作。 1、复合查询 因为ES提供了一些Restful风格的接口&#xff0c;可以让任何语言去调用&#xff0c;因此我们可以将之前的请求地址粘贴到Multi ElasticSearch Head插件里面&#xff0c;选择GET请求方式&#x…

WordPress主题YIA如何将首页的置顶小工具改为站长推荐小工具?

YIA主题有“置顶推荐”小工具&#xff0c;首页文章列表页有置顶功能&#xff0c;可在YIA主题设置 >> 列表 >> 首页-最新发布 >> 显示置顶文章中开启或关闭。如果将“置顶推荐”小工具添加到“首页顶栏”&#xff0c;同时也开启首页最新发布的“显示置顶文章”…

Java使用规范

1.关键字 定义&#xff1a;被Java语言赋予了特殊含义&#xff0c;用做专门用途的字符串(单词) 特点&#xff1a;关键字中的所有字母都是小写 2.保留字 java保留字&#xff1a;现有Java版本尚未使用&#xff0c;但以后的版本可能会作为关键字使用。命名标识符时要避免使用这些…

C# wpf 字体图标预览,html字符与unicode转换

在进行wpf 开发工作过程中遇到字体图标无法预览的问题&#xff0c;特此记录。 1、把需要预览的字体文件上传到网站上进行转换 Create Your Own font-face Kits Font Squirrel2、下载文件后进行解压。 3、找到 Glyph Chart 查看字体html字符编码4、在wpf中直接使用即可 <…

C#,河豚算法(Blowfish Algorithm)的加密、解密源代码

Bruce Schneier 1 河豚算法&#xff08;Blowfish Algorithm&#xff09; 河豚算法&#xff08;Blowfish Algorithm&#xff09;是1993年11月由Bruce Schneier设计的一个完全开源的算法。 Blowfish算法是一个分组长度为64位、密钥长度可变的对称分组密码算法。 Blowfish算法具…

Redis 持久化对性能有何影响?

Redis 持久化对性能的影响 Redis 是一个高性能的内存数据存储系统&#xff0c;通常被用于缓存、消息队列和数据存储等方面。由于 Redis 是基于内存的&#xff0c;因此它的读写速度非常快&#xff0c;可以满足高并发、低延迟的应用需求。但是&#xff0c;当 Redis 需要持久化数…

Git的一些基本操作

初始git 我们给出下面的一个场景&#xff0c;在大学里&#xff0c;一些老师在我们做完实验之后喜欢让我们交实验报告&#xff0c;假设我们有一个比较追求完美的老师和一个勤奋的学生&#xff0c;这个学生叫做小帅&#xff0c;那天小帅桑勤奋的完成实验报告&#xff0c;在第二天…

L1-016 查验身份证-java

输入样例1&#xff1a; 4 320124198808240056 12010X198901011234 110108196711301866 37070419881216001X输出样例1&#xff1a; 12010X198901011234 110108196711301866 37070419881216001X输入样例2&#xff1a; 2 320124198808240056 110108196711301862输出样例2&#…

银行数据仓库体系实践(18)--数据应用之信用风险建模

信用风险 银行的经营风险的机构&#xff0c;那在第15节也提到了巴塞尔新资本协议对于银行风险的计量和监管要求&#xff0c;其中信用风险是银行经营的主要风险之一&#xff0c;它的管理好坏直接影响到银行的经营利润和稳定经营。信用风险是指交易对手未能履行约定契约中的义务而…

【AIGC核心技术剖析】DreamCraft3D一种层次化的3D内容生成方法

DreamCraft3D是一种用于生成高保真、连贯3D对象的层次化3D内容生成方法。它利用2D参考图像引导几何塑造和纹理增强阶段&#xff0c;通过视角相关扩散模型执行得分蒸馏采样&#xff0c;解决了现有方法中存在的一致性问题。使用Bootstrapped Score Distillation来提高纹理&#x…

Backtrader 文档学习- Observers

Backtrader 文档学习- Observers 1.概述 在backtrader中运行的策略主要处理数据源和指标。 数据源被加载到Cerebro实例中&#xff0c;并最终成为策略的一部分&#xff08;解析和提供实例的属性&#xff09;&#xff0c;而指标则由策略本身声明和管理。 到目前为止&#xff0c…

python文字识别

Tesseract 文字识别是ORC的一部分内容&#xff0c;ORC的意思是光学字符识别&#xff0c;通俗讲就是文字识别。Tesseract是一个用于文字识别的工具。 Tesseract的安装及配置 https://digi.bib.uni-mannheim.de/tesseract/ 在上述链接下载自己需要的版本。下载后安装&#xff…

chisel之scala 语法

Chisel新手教程之Scala语言&#xff08;1&#xff09; Value & variable Value是immutable的&#xff0c;当它被分配一个数据后&#xff0c;无法进行重新分配。用 val 表示。 Variable是mutable的&#xff0c;可以重复赋值。用 var 表示。示例如下&#xff1a; val a …

视觉SLAM十四讲学习笔记(一)初识SLAM

目录 前言 一、传感器 1 传感器分类 2 相机 二、经典视觉 SLAM 框架 1 视觉里程计 2 后端优化 3 回环检测 4 建图 5 SLAM系统 三、SLAM 问题的数学表述 四、Ubuntu20.04配置SLAM十四讲 前言 SLAM: Simultaneous Localization and Mapping 同时定位与地图构建&#…

R语言阈值效应函数cut.tab2.0版发布(支持线性回归、逻辑回归、cox回归,自定义拐点)

阈值效应和饱和效应是剂量-反应关系中常见的两种现象。阈值效应是指当某种物质的剂量达到一定高度时&#xff0c;才会对生物体产生影响&#xff0c;而低于这个剂量则不会产生影响。饱和效应是指当某种物质的剂量达到一定高度后&#xff0c;其影响不再随剂量的增加而增加&#x…

2024-2-4-复习作业

源代码&#xff1a; #include <stdio.h> #include <stdlib.h> typedef int datatype; typedef struct Node {datatype data;struct Node *next;struct Node *prev; }*DoubleLinkList;DoubleLinkList create() {DoubleLinkList s(DoubleLinkList)malloc(sizeof(st…

大白话介绍循环神经网络

循环神经网络实质为递归式的网络&#xff0c;它在处理时序任务表现出优良的效果&#xff0c;毕竟递归本来就是一步套一步的向下进行&#xff0c;而自然语言处理任务中涉及的文本天然满足这种时序性&#xff0c;比如我们写字就是从左到右一步步来的鸭&#xff0c;刚接触深度学习…

【transformer】Hugging Face 安装环境(03/10)

一、说明 关于transformer库的安装环境的说明&#xff1b;因为transformer是一个不小的大型软件&#xff0c;安装的时候对环境还是需要一定规划&#xff0c;一般安装在虚拟环境中&#xff0c;以便与常规软件进行隔离。 二、安装 为您正在使用的任何深度学习库安装 Transformer&…