【算法与数据结构】496、503、LeetCode下一个更大元素I II

news2024/10/7 16:23:00

文章目录

  • 一、496、下一个更大元素 I
  • 二、503、下一个更大元素II
  • 三、完整代码

所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。

一、496、下一个更大元素 I

在这里插入图片描述

  思路分析:本题思路和【算法与数据结构】739、LeetCode每日温度类似。如果用暴力破解法时间复杂度需要 O ( m ∗ n ) O(m*n) O(mn),其中 m m m n n n分别是两个数组的长度。单调栈只需要 O ( n + m ) O(n+m) O(n+m)的时间复杂度。相较于739题,本题需要找到nums1元素在nums2数组中的位置,那么我们可以利用unordered_map,查找和增删效率是最高的【算法与数据结构】算法与数据结构知识点:

	unordered_map<int, int> umap; // key:下标元素,value:下标
	for (int i = 0; i < nums1.size(); i++) {
		umap[nums1[i]] = i;
	}

  然后利用739题的单调栈思路,遍历nums2数组。每当当前遍历元素大于栈顶元素,并且nums2数组的元素在nums1中存在(umap.count(nums2[st.top()]) > 0就是统计数量,大于零说明nums2[st.top()]元素存在),我们找到栈顶元素在nums1中的下标,在结果数组中根据下标修改其值:

	for (int i = 0; i < nums2.size(); i++) {			
		while (!st.empty() && nums2[i] > nums2[st.top()]) {
			if (umap.count(nums2[st.top()]) > 0) { // 看map里是否存在这个元素,count函数计算数量
				int index = umap[nums2[st.top()]]; // 根据map找到nums2[st.top()] 在 nums1中的下标
				result[index] = nums2[i];
			}
			st.pop();
		}
		st.push(i); // 插入数组的下标
	}

  程序如下

// 496、下一个更大元素 I
class Solution {
public:
	vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
		vector<int> result(nums1.size(), -1);
		stack<int> st;
		unordered_map<int, int> umap; // key:下标元素,value:下标
		for (int i = 0; i < nums1.size(); i++) {
			umap[nums1[i]] = i;
		}
		for (int i = 0; i < nums2.size(); i++) {			
			while (!st.empty() && nums2[i] > nums2[st.top()]) {
				if (umap.count(nums2[st.top()]) > 0) { // 看map里是否存在这个元素,count函数计算数量
					int index = umap[nums2[st.top()]]; // 根据map找到nums2[st.top()] 在 nums1中的下标
					result[index] = nums2[i];
				}
				st.pop();
			}
			st.push(i); // 插入数组的下标
		}
		return result;
	}
};

复杂度分析:

  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( n ) O(n) O(n)

二、503、下一个更大元素II

在这里插入图片描述

  思路分析:本题和496题不同之处在于从两个数组变成一个数组,然后数组是环形数组。针对环形数组,我们要比较大小,可以将环形数组复制一份,两个相同的数组扩充成一个新数组。然后在新数组上去做单调栈的操作。
  程序如下

// 503、下一个更大元素II-版本一
class Solution2 {
public:
	vector<int> nextGreaterElements(vector<int>& nums) {
		vector<int> nums1(nums.begin(), nums.end()); // 拼接一个新的nums
		nums.insert(nums.end(), nums1.begin(), nums1.end());		
		vector<int> result(nums.size(), -1);	// 用新的nums大小来初始化result

		// 开始单调栈
		stack<int> st;
		st.push(0);
		for (int i = 1; i < nums.size(); i++) {
			while (!st.empty() && nums[i] > nums[st.top()]) {
				result[st.top()] = nums[i];
				st.pop();
			}
			st.push(i);
		}
		result.resize(nums.size() / 2);		// 最后再把结果集即result数组resize到原数组大小
		return result;
	}
};

  虽然这种写法比较直观,但是做了很多无用操作。resize函数是O(1)的操作,但扩充nums数组相当于多了一个O(n)的操作。其实也可以不扩充nums,而是在遍历的过程中模拟走了两边nums。例如我们改变索引的上界,然后令其做取nums.size()模的操作。

// 503、下一个更大元素II-版本二
class Solution3 {
public:
	vector<int> nextGreaterElements(vector<int>& nums) {
		vector<int> result(nums.size(), -1);
		stack<int> st;
		for (int i = 0; i < nums.size() * 2; i++) {
			// 模拟遍历两边nums,注意一下都是用i % nums.size()来操作
			while (!st.empty() && nums[i % nums.size()] > nums[st.top()]) {
				result[st.top()] = nums[i % nums.size()];
				st.pop();
			}
			st.push(i % nums.size());
		}
		return result;
	}
};

复杂度分析:

  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( n ) O(n) O(n)

三、完整代码

# include <iostream>
# include <vector>
# include <unordered_map>.
# include <stack>
using namespace std;

// 496、下一个更大元素 I
class Solution {
public:
	vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
		vector<int> result(nums1.size(), -1);
		stack<int> st;
		unordered_map<int, int> umap; // key:下标元素,value:下标
		for (int i = 0; i < nums1.size(); i++) {
			umap[nums1[i]] = i;
		}
		for (int i = 0; i < nums2.size(); i++) {			
			while (!st.empty() && nums2[i] > nums2[st.top()]) {
				if (umap.count(nums2[st.top()]) > 0) { // 看map里是否存在这个元素,count函数计算数量
					int index = umap[nums2[st.top()]]; // 根据map找到nums2[st.top()] 在 nums1中的下标
					result[index] = nums2[i];
				}
				st.pop();
			}
			st.push(i); // 插入数组的下标
		}
		return result;
	}
};

// 503、下一个更大元素II-版本一
class Solution2 {
public:
	vector<int> nextGreaterElements(vector<int>& nums) {
		vector<int> nums1(nums.begin(), nums.end()); // 拼接一个新的nums
		nums.insert(nums.end(), nums1.begin(), nums1.end());		
		vector<int> result(nums.size(), -1);	// 用新的nums大小来初始化result

		// 开始单调栈
		stack<int> st;
		st.push(0);
		for (int i = 1; i < nums.size(); i++) {
			while (!st.empty() && nums[i] > nums[st.top()]) {
				result[st.top()] = nums[i];
				st.pop();
			}
			st.push(i);
		}
		result.resize(nums.size() / 2);		// 最后再把结果集即result数组resize到原数组大小
		return result;
	}
};

// 503、下一个更大元素II-版本二
class Solution3 {
public:
	vector<int> nextGreaterElements(vector<int>& nums) {
		vector<int> result(nums.size(), -1);
		if (nums.size() == 0) return result;
		stack<int> st;
		for (int i = 0; i < nums.size() * 2; i++) {
			// 模拟遍历两边nums,注意一下都是用i % nums.size()来操作
			while (!st.empty() && nums[i % nums.size()] > nums[st.top()]) {
				result[st.top()] = nums[i % nums.size()];
				st.pop();
			}
			st.push(i % nums.size());
		}
		return result;
	}
};

int main() {
	//vector<int> nums1 = { 4,1,2 };
	//vector<int> nums2 = { 1,3,4,2 };
	//Solution s1;
	//vector<int> result = s1.nextGreaterElement(nums1, nums2);

	vector<int> nums = { 1,2,3,4,3 };
	Solution2 s1;
	vector<int> result = s1.nextGreaterElements(nums);

	for (vector<int>::iterator i = result.begin(); i != result.end(); i++) {
		cout << *i << " ";
	}
	cout << endl;

	system("pause");
	return 0;
}

end

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

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

相关文章

【VTKExamples::PolyData】第二十四期 InterpolateTerrain

很高兴在雪易的CSDN遇见你 VTK技术爱好者 QQ:870202403 前言 本文分享VTK样例InterpolateTerrain,希望对各位小伙伴有所帮助! 感谢各位小伙伴的点赞+关注,小易会继续努力分享,一起进步! 你的点赞就是我的动力(^U^)ノ~YO 1. InterpolateTerrain 输出: Interp…

精灵图,字体图标,CSS3三角

精灵图 1.1为什么需要精灵图 一个网页中往往会应用很多小的背景图像作为修饰&#xff0c;当网页中的图像过多时&#xff0c;服务器就会频繁的接受和发送请求图片&#xff0c;造成服务器请求压力过大&#xff0c;这将大大降低页面的加载速度。 因此&#xff0c;为了有效地减少…

深入Java容器:概览、设计模式与源码分析

深入Java容器&#xff1a;概览、设计模式与源码分析 Java 容器一、概览Collection1. Set2. List3. Queue Map 二、容器中的设计模式迭代器模式适配器模式 三、源码分析ArrayList1. 概览2. 扩容3. 删除元素4. 序列化5. Fail-Fast Vector1. 同步2. 扩容3. 与 ArrayList 的比较4. …

Java与MySQL的精准结合:打造高效审批流程

1流程思路分析 审批流程&#x1f431;‍&#x1f4bb; 1.串行流程 当前节点审批完成后&#xff0c;下一次节点才能进行操作&#xff0c;例如经理通过之后&#xff0c;总监才能审批&#xff1b; 2.并行流程 一个审批节点需要多人联审。一般有两种方式&#xff1a;会签、或签…

Python中的嵌套字典访问与操作详解

前言 在Python编程中&#xff0c;嵌套字典是一种常见的数据结构&#xff0c;它可以以层次结构的方式组织和存储数据。嵌套字典通常包含字典内嵌套在其他字典中&#xff0c;创建了一种多层级的数据结构。本文将详细介绍如何在Python中访问和操作嵌套字典&#xff0c;包括访问、…

视频无损放大修复工具Topaz Video AI 新手入门教程

想要自学Topaz Video AI &#xff1f;Topaz Video AI 如何使用&#xff1f;这里给大家带来了视频无损放大修复工具Topaz Video AI 新手入门教程&#xff0c;快来看看吧&#xff01; 下载&#xff1a;Topaz Video AI for mac 导入您的文件 有两种方法可以将文件导入 Topaz Vid…

C++重新入门-C++变量作用域

目录 1.C变量定义 2.C作用域 3.局部变量 4.全局变量 5.块作用域变量 6.初始化局部变量和全局变量 1.C变量定义 一般来说有三个地方可以定义变量&#xff1a; 在函数或一个代码块内部声明的变量&#xff0c;称为局部变量。 在函数参数的定义中声明的变量&#xff0c;称为…

【博云2023】乘龙一跃腾云海,侧目抬手摘星河

癸卯渐远&#xff0c;甲辰渐至&#xff0c;预示着被汗水浇灌的种子&#xff0c;必将顶开冻土&#xff0c;迎接阳光。 每逢春节&#xff0c;当亲友彼此问候&#xff0c;博云人总能自豪地说&#xff0c;我们认真地、努力地奋斗&#xff0c;让我们能自信地踏上新的征程。 我们的…

架构(十二)动态Excel

一、引言 作者最近的平台项目需要生成excel&#xff0c;excel的导入导出是常用的功能&#xff0c;但是作者想做成动态的&#xff0c;不要固定模板&#xff0c;那就看看怎么实现。 二、后端 先捋一下原理&#xff0c;前后端的交互看起来是制定好的接口&#xff0c;其实根本上是…

安全的接口访问策略

渗透测试 一、Token与签名 一般客户端和服务端的设计过程中&#xff0c;大部分分为有状态和无状态接口。 一般用户登录状态下&#xff0c;判断用户是否有权限或者能否请求接口&#xff0c;都是根据用户登录成功后&#xff0c;服务端授予的token进行控制的。 但并不是说有了tok…

4核8G服务器配置性能怎么样?12M带宽配置服务器能干什么?

腾讯云轻量4核8G12M轻量应用服务器支持多少人同时在线&#xff1f;通用型-4核8G-180G-2000G&#xff0c;2000GB月流量&#xff0c;系统盘为180GB SSD盘&#xff0c;12M公网带宽&#xff0c;下载速度峰值为1536KB/s&#xff0c;即1.5M/秒&#xff0c;假设网站内页平均大小为60KB…

16.1 Spring框架_SpringIoC容器与Bean管理(❤❤❤❤)

16.1 Spring框架_SpringIoC容器与Bean管理 1. Spring IOC1.1 IoC控制反转 1. Spring IOC 1.1 IoC控制反转 需要自己查找3种苹果的特色,从而选择符合自己的需求 告诉水果店老板自己的口味,由老板推荐哪种苹果,省去自己查询水果特点 在java中,各种水果就是各种对象,买水果就是创…

问题:2、计算机网络的目标是实现________。 #媒体#知识分享

问题&#xff1a;2、计算机网络的目标是实现________。 A&#xff0e;数据处理 B&#xff0e;信息传输与数据处理 C&#xff0e;资源共享与信息传输 D&#xff0e;文献查询 参考答案如图所示

【用pycharm安装第三方库时出现错误】【‘pip‘ 不是内部或外部命令,也不是可运行的程序或批处理文件。】

目录 一、问题描述 二、解决过程 1、pip的版本不是最新版本导致安装不了第三方库 2、pip最新版本安装出错 3、pip 不是内部或外部命令&#xff0c;也不是可运行的程序或批处理文件” 4、 ERROR: Could not find a version that satisfies the requirement PIL (from versi…

政安晨:示例演绎机器学习中(深度学习)神经网络的数学基础——快速理解核心概念(二){两篇文章讲清楚}

这一篇与上一篇是兄弟篇&#xff0c;意在通过两篇文章讲清楚深度学习中神经网络的数学基础&#xff0c;第一次看到这篇文章的小伙伴可以从上一篇文章看起&#xff08;包括搭建环境等等都在上一篇&#xff09;&#xff0c;上一篇链接如下&#xff1a; 政安晨&#xff1a;示例演…

Flink基础篇|001_Flink是什么

&#x1f4eb; 作者简介&#xff1a;「六月暴雪飞梨花」&#xff0c;专注于研究Java&#xff0c;就职于科技型公司后端工程师 &#x1f3c6; 近期荣誉&#xff1a;华为云云享专家、阿里云专家博主、腾讯云优秀创作者 &#x1f525; 三连支持&#xff1a;欢迎 ❤️关注、&#x…

Linux系统调试课:Linux错误码介绍

文章目录 一、错误码二、错误码返回案例三、使用 goto 语句沉淀、分享、成长,让自己和他人都能有所收获!😄 📢错误代码由内核或用户空间应用程序(通过errno变量)解释。错误处理在软件开发中非常重要,而不仅仅是在内核开发中。幸运的是,内核提供的几种错误,几乎涵盖了可…

InternLM大模型实战-1.书生浦语大模型全链路开源体系

文章目录 前言笔记正文大模型成为热门关键词书生浦语开源历程从模型到应用书生浦语全链条开源开放体系数据预训练微调评测部署部署智能体LagentAgentLego 总结 前言 本系列文章是参与书生浦语全链路开源体系学习的笔记文章。B站视频教程地址&#xff1a; 笔记正文 大模型成为…

【笔记】Harmony学习:下载安装 DevEco Studio 开发工具IDE

IDE 安装 从官网下载DevEco Studio 安装包后进行安装&#xff0c; 安装完毕后&#xff0c;本地环境可能要配置相关工具&#xff0c;可以通过下面的诊断检测一下本地环境&#xff0c;通过蓝色“Set it up now” 可以快速安装。 1. Node.js (for ohpm) 2. ohpm 下载op的包管理&a…

项目学习记录

项目开发 创建项目环境配置关联git新增模块项目启动打印地址日志使用httpclient进行idea内部控制台测试使用AOP拦截器打印日志 创建项目 创建一个空项目&#xff0c;并勾选下面选项 然后进入pom.xml中修改项目配置 根据这个链接选则&#xff0c;修改项目的支持版本 链接&#…