LeetCode刷题篇—496.下一个更大的元素(一)

9 篇文章 0 订阅
6 篇文章 0 订阅
本文介绍了如何使用辅助栈和单调栈两种方法解决LeetCode中的496题,通过实例演示了如何查找nums1数组中每个元素在nums2数组中的下一个更大元素。两种策略分别适用于不同场景,辅助栈适用于元素逐个比较,而单调栈则利用单调性优化查找过程。
摘要由CSDN通过智能技术生成

LeetCode刷题篇—496.下一个更大的元素(一)

题目

给你两个 没有重复元素 的数组 nums1 和 nums2 ,其中nums1 是 nums2 的子集。

请你找出 nums1 中每个元素在 nums2 中的下一个比其大的值。

nums1 中数字 x 的下一个更大元素是指 x 在 nums2 中对应位置的右边的第一个比 x 大的元素。如果不存在,对应位置输出 -1 。

在这里插入图片描述

思路

1、辅助栈
根据之前一题所讲的辅助栈的思想,通常是除了所有元素所在栈之外,另开辟新的栈存储一些变量。对于本题,辅助栈的意义在于暂时存放那些从栈中弹出用于比较的元素。
(1)遍历nums2,将其全部放入stack1中;
(2)取出stack1的栈顶元素,将其与nums1数组中的数比较,若大,则更新max——“下一个更大元素”,若相等,则说明已经找完目标元素之后的每个数,需停止遍历,若小,则不做处理;之后将取出的栈顶元素压入辅助栈stack2中。
(3)随着遍历更新max,最终找到距离最近的“下一个”更大元素,将其放入数组中;
(4)为了方便对nums1数组中的下一个元素进行同样的操作,再将辅助栈stack2中的每个元素放回stack1中;
(5)遍历nums1数组,执行(2)(3)(4);
2、单调栈,即一个栈内元素从栈顶到栈底具有单调性的栈,在利用这个方法时,不像前一种方法先一股脑的将nums2全部入栈,而是将要入栈的元素与栈顶元素进行比较,如果即将要入栈的元素大,则表示已经找到了“下一个更大元素”,就将栈顶元素出栈,和即将入栈的元素一起存入哈希表中构成映射关系,这样nums1中的元素只需要去哈希表中找对应元素即可。
(1)遍历nums2数组,在栈为空时,将nums2[i]入栈;
(2)在栈不为空且即将入栈的元素>栈顶元素时,弹出栈顶元素,与即将入栈的元素一起存入哈希表中;然后再将这个即将入栈的元素真正入栈;
(3)遍历完成nums2数组,构建完成哈希映射
(4)如果即将入栈的元素不大于栈顶元素,那么它就会直接入栈,如果遍历完数组之后,栈中还有元素,则说明这些元素不存在“下一个更大元素”,便把它们加入哈希表中映射为-1;

求解方法

1、辅助栈

vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
		//辅助栈;时间复杂度O(MN),用到了双层循环,空间复杂度O(N)
		vector<int>result;
		stack<int>st;
		stack<int>temp;
		int top;
		for (int i = 0; i < nums2.size(); i++)
		{
			st.push(nums2[i]);
		}
		for (int i = 0; i < nums1.size(); i++)
		{
			int max = -1;
			bool isFound = false;
			while (!st.empty() && !isFound)
			{
				top = st.top();
				st.pop();
				if (top > nums1[i]) max = top;
				else if (top == nums1[i]) isFound = true;
				temp.push(top);
			}
			result.push_back(max);
			while (!temp.empty())
			{
				int m_top = temp.top();
				st.push(m_top);
				temp.pop();
			}
		}
		return result;
	}

2、单调栈

vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
		stack<int> st;
		map<int, int> m_map;
		vector<int> result;
		for (int i = 0; i < nums2.size(); i++)
		{
			while (!st.empty() && nums2[i] > st.top())
			{			
				m_map[st.top()] = nums2[i];
				st.pop();
			}
			st.push(nums2[i]);
		}
		while (!st.empty())
		{
			int temp = st.top();
			m_map[temp] = -1;
			st.pop();
		}
		for (int i = 0; i < nums1.size(); i++)
		{
			result.push_back(m_map[nums1[i]]);
		}
		return result;
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值