【leetcode】496. 下一个更大元素 I (单调栈)

https://leetcode-cn.com/problems/next-greater-element-i/

#include <stack>
#include <unordered_map>
using std::stack;
using std::unordered_map;

// https://leetcode-cn.com/problems/next-greater-element-i/
// 单调栈 https://blog.youkuaiyun.com/lucky52529/article/details/89155694
vector<int> StackAbout::nextGreaterElement(vector<int>& nums1, vector<int>& nums2)
{
	
	stack<int> s;
	unordered_map<int, int> ans;

	for (int i = nums2.size() - 1; i >= 0; i--)
	{
		while (!s.empty() && nums2[i] >= s.top())
		{
			s.pop(); // 栈内,最大的值永远最底下
		}	
		ans[nums2[i]] = s.empty() ? -1: s.top(); // 注意这两条语句的先后顺序
		s.push(nums2[i]); // 注意这两条语句的先后顺序
	}

	vector<int> res(nums1.size());
	// 在这之前,根本不考虑nums1这个数组
	for (int i = 0; i < nums1.size(); i++)
	{
		res[i] = ans[nums1[i]]; // 前提条件:子集
	}

	return res;
}
要使用单调栈算法在 C++ 中找到数组中每个元素右侧第一个比它大的元素,可以通过以下方式实现。该算法利用栈来维护一个递减序列,确保栈顶元素始终小于当前遍历到的元素,从而快速找到右侧第一个更大元素。 ### 实现思路 1. 初始化一个栈 `s` 用于存储数组元素的索引。 2. 初始化一个结果数组 `res`,大小与输入数组相同,初始值为 `-1`(表示某些元素可能没有右侧更大元素)。 3. 遍历数组中的每个元素: - 如果栈不为空且当前元素大于栈顶索引对应的元素,则将栈顶索引弹出,并将当前元素赋值给结果数组中对应的位置。 - 否则,将当前索引压入栈中。 4. 遍历结束后,栈中剩余的索引对应的元素没有找到右侧更大元素,结果数组中对应位置保持为 `-1`。 ### C++ 代码实现 ```cpp #include <iostream> #include <vector> #include <stack> using namespace std; vector<int> findNextGreaterElements(vector<int>& nums) { int n = nums.size(); vector<int> res(n, -1); // 初始化结果数组为-1 stack<int> s; // 栈用于存储元素的索引 for (int i = 0; i < n; ++i) { // 当栈不为空且当前元素大于栈顶索引对应的元素时 while (!s.empty() && nums[i] > nums[s.top()]) { int index = s.top(); s.pop(); res[index] = nums[i]; // 更新结果数组 } s.push(i); // 将当前索引压入栈中 } return res; } int main() { vector<int> nums = {1, 3, 4, 2}; vector<int> result = findNextGreaterElements(nums); cout << "每个元素右侧第一个更大元素为:" << endl; for (int val : result) { cout << val << " "; } cout << endl; return 0; } ``` ### 示例输出 对于输入数组 `{1, 3, 4, 2}`,程序将输出: ``` 每个元素右侧第一个更大元素为: 3 4 -1 -1 ``` ### 复杂度分析 - **时间复杂度**:O(n),其中 n 是数组的长度。每个元素最多入栈和出栈一次,因此时间复杂度为线性。 - **空间复杂度**:O(n),用于存储栈和结果数组的空间。 ### 应用场景 该算法适用于需要快速找到数组中每个元素右侧第一个更大元素的问题,例如在解决 **LeetCode 496.一个更大元素 I** 和 **LeetCode 503.一个更大元素 II** 等问题时,可以使用此方法提高效率[^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值