单调栈 —— Next Greater Element

什么是单调栈?

就是栈内元素单调递增或单调递减的栈!
单调栈一般用作求解 Next Greater Element 问题:寻找下一个更大(更小)的元素。
假设一个数组 [ 3, 7, 5, 11, 4, 8, 6],我们想要找到这个数组每个元素后面第一个更大元素,
一般我们直接按顺序进行遍历的暴力解法的时间复杂度是O(n^2)。
但是,如果我们使用一个栈来操作:
在这里插入图片描述

  1. 将第一个数组元素入栈;
  2. 将后一个数组元素与栈顶元素比较,如果小于栈顶元素则入栈,如果大于栈顶元素则将栈顶元素出栈;
  3. 依次遍历所有数组元素,最后还在栈中的元素,表示其后没有更大元素。

时间复杂度为O(n)。

练习题

本文所有练习题均Ctrl+C引自力扣(leetcode)

1.下一个更大元素

题目:
给定两个 没有重复元素 的数组 nums1 和 nums2 ,其中nums1 是 nums2 的子集。找到 nums1 中每个元素在 nums2 中的下一个比其大的值。

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

示例:

输入: nums1 = [4,1,2], nums2 = [1,3,4,2].
输出: [-1,3,-1]
解释: 
nums1 中第一个元素 4 在 nums2 中出现在第三个元素位置,其右没有更大元素, 返回 -1;
nums1 中第二个元素 1 在 nums2 中出现在第一个元素位置,其右第一个更大元素为3, 返回 3;
nums1 中第三个元素 2 在 nums2 中出现在最后位置,其右没有更大元素, 返回 -1;

输入: nums1 = [2,4], nums2 = [1,2,3,4].
输出: [3,-1]

思路:

  1. 暴力解法:
    使用两个下标和一个用来记录结果的数组,向右遍历第一个数组每个元素,先在第二个数组中找到与第一数组元素(nums1[Index])相等的那个元素(nums2[hignerIndex]),在继续向右遍历直到找到一个比第一数组对应元素更大的元素(nums1[Index] < nums2[higherIndex]),如果找到就将该元素存入结果数组,如果没有找到就存入-1。
int[] ans = new int[]; 	// 结果数组
for ( int Index =0; Index < nums1.Length; Index++ ){
	int higherIndex = 0; 	// 第二个数组的下标
	// 遍历第二个数组,寻找相等元素
	for ( int i = 0; i < nums2.Length; i++ ){
		if ( nums1[Index] = nums2[i] ){
			higherIndex = i;
			break;
		}
	}
	// 继续遍历第二个数组,直到超出索引或者找到更大的元素
	while (  higherIndex < nums2.Length && nums2[higherIndex] <= nums1[Index] ){
		higherIndex++;
	}
	if ( higherIndex < nums2.Length ){
		// 找到更大的元素,对应元素存入结果数组
		ans[Index] = nums2[higherIndex];
	}else{
		// 没有找到更大的元素,结果数组存入-1
		ans[Index] = -1;
	}	 
}
  1. 单调栈:
    先不管第一个数组 nums1 , 直接对第二个数组 nums2 中的元素操作,找出每个元素后面的更大的元素,将它们存入哈希表中,之后再遍历 nums1 ,从哈希表中找出答案。

题解(python)

class Solution:
    
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值