LeetCode 单调栈 下一个更大元素 I

下一个更大元素 I

nums1 中数字 x 的 下一个更大元素 是指 x 在 nums2 中对应位置 右侧 的 第一个 比 x 大的元素。

给你两个 没有重复元素 的数组 nums1 和 nums2 ,下标从 0 开始计数,其中nums1 是 nums2 的子集。

对于每个 0 <= i < nums1.length ,找出满足 nums1[i] == nums2[j] 的下标 j ,并且在 nums2 确定 nums2[j] 的 下一个更大元素 。如果不存在下一个更大元素,那么本次查询的答案是 -1 。

返回一个长度为 nums1.length 的数组 ans 作为答案,满足 ans[i] 是如上所述的 下一个更大元素 。

示例 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] <= 104

nums1和nums2中所有整数 互不相同

nums1 中的所有整数同样出现在 nums2 中

进阶:你可以设计一个时间复杂度为 O(nums1.length + nums2.length) 的解决方案吗?

题解

根据题意,我们需要找到数组 nums2 中的每元素的 最先的 下一个 更大的元素,没有则为-1

根据 最先的 下一个 更大的元素,我们采用单调栈进行解题

首先我们分析一下如何找到最先的下一个更大的元素

我们可以对于每一个 nums2 元素都进行遍历,寻找其后面的比他大的元素

但是这样的时间复杂度太高了

遍历完数组 nums2 需要 O(n^2)

所以我们采用单调栈对算法进行优化

我们可以这么理解 如何找到找到最先的下一个更大的元素

图片来源

作者:labuladong

链接:https://leetcode.cn/problems/next-greater-element-i/solutions/8877/dan-diao-zhan-jie-jue-next-greater-number-yi-lei-w/

来源:力扣(LeetCode)

例如:此时我们需要寻找 nums[ i ] 的下一个更大的元素

如果之后有元素 小于 nums[ i ] ,那么它就被 nums[ i ] 给挡住了,在 nums[ i ] 之前的所有元素都不可能看见它了

也就是说

当寻找 nums[ i ] 的下一个更大的元素时,我们只需要记得 nums[ i ] 和比 nums[ i ] 更大的元素

比 nums[ i ] 小的都被挡住了,所以就不需要考虑了

那么我就可以使用单调栈对这一信息进行存储

对于遍历到的 nums[ i ]

首先将栈中所有比它小的元素都出栈

如果此时栈不为空则栈顶的元素就是 nums[ i ] 的下一个更大的元素

else 说明没有更的,依据要求为 -1

然后将 nums[ i ] 进栈即可

关于上述操作的时间复杂度

虽然使用了两层循环,但是我们可以发现

内层循环 即出栈操作

当整个循环结束后,最多也就执行 n 次

所以整个循环的时间复杂度是 O(n)

接下来要考虑的问题就是如何存储 nums[ i ] 的下一个更大的元素这些数据

由于题目是根据来进行查找的

我们便使用哈希表将值对应的下一个更大的元素进行存储

最后遍历数组 nums1

根据值取访问哈希表得到数据即可

代码如下↓

c 复制代码
/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* nextGreaterElement(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize) {
    *returnSize = nums1Size;
    int arr[10001];
    int* res = (int*)malloc(sizeof(int)*nums1Size);
    int stack[nums2Size];
    int f = -1;
    for(int i=nums2Size-1;i>-1;i--)
    {
        while(f!=-1 && nums2[i]>stack[f])
        {
            f--;
        }
        if(f==-1)
        {
            arr[nums2[i]]=-1;
        }
        else
        {
            arr[nums2[i]]=stack[f];
        }
        stack[++f]=nums2[i];
    }
    for(int i=0;i<nums1Size;i++)
    {
        res[i]=arr[nums1[i]];
    }
    return res;
}
相关推荐
星语心愿.26 分钟前
D4——贪心练习
c++·算法·贪心算法
光头man27 分钟前
【八大排序(二)】希尔排序
算法·排序算法
武昌库里写JAVA35 分钟前
使用React Strict DOM改善React生态系统
数据结构·vue.js·spring boot·算法·课程设计
创意锦囊1 小时前
随时随地编码,高效算法学习工具—E时代IDE
ide·学习·算法
stm 学习ing1 小时前
HDLBits训练3
c语言·经验分享·笔记·算法·fpga·eda·verilog hdl
single5941 小时前
【c++笔试强训】(第四十一篇)
java·c++·算法·深度优先·图论·牛客
yuanbenshidiaos1 小时前
C++-----函数与库
开发语言·c++·算法
清弦墨客1 小时前
【数据结构与算法】深度优先搜索:树与图的路径探寻之道
数据结构·python·算法·蓝桥杯·深度优先
尘觉1 小时前
算法的学习笔记—扑克牌顺子(牛客JZ61)
数据结构·笔记·学习·算法
1 9 J1 小时前
Java 上机实践11(组件及事件处理)
java·开发语言·学习·算法