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;
}
相关推荐
你撅嘴真丑12 分钟前
map 与 set容器的应用--话题焦点人物
数据结构
生成论实验室20 分钟前
《事件关系阴阳博弈动力学:识势应势之道》第二篇:阴阳博弈——认知的动力学基础
数据结构·人工智能·科技·神经网络·算法
li16709027032 分钟前
第二十七章:智能指针
c语言·数据结构·c++·visual studio
风筝在晴天搁浅1 小时前
字节高频题 小于n的最大数
算法
LabVIEW开发1 小时前
LabVIEW水力机组空蚀在线监测
算法·labview·labview知识·labview功能·labview程序
AI科技星1 小时前
科幻艺术书本封面:《全域数学》第一部·数术本源 第三卷 代数原本(P95-141)完整五级目录【乖乖数学】
算法·机器学习·数学建模·数据挖掘·量子计算
风筝在晴天搁浅1 小时前
LeetCode 92.反转链表Ⅱ
算法·leetcode·链表
王老师青少年编程1 小时前
csp信奥赛C++高频考点专项训练之贪心算法 --【贪心与二分判定】:数列分段 Section II
c++·算法·贪心·csp·信奥赛·二分判定·数列分段 section ii
V搜xhliang02462 小时前
OpenClaw科研全场景用法:从文献到实验室的完整自动化方案
运维·开发语言·人工智能·python·算法·microsoft·自动化
汉克老师2 小时前
GESP2025年3月认证C++五级( 第三部分编程题(2、原根判断))
c++·算法·模运算·gesp5级·gesp五级·原根·分解质因数