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

下一个更大元素 I

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

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

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

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

示例 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 <= nums1i, nums2i <= 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;
}
相关推荐
_Narcissus_17 分钟前
二分算法笔记及例题
数据结构·c++·笔记·算法·蓝桥杯·查找·二分算法
tachibana225 分钟前
RAGAS 指标解读
数据库·人工智能·算法·机器学习·架构·大模型·llm
qq_419563091 小时前
ToT 的 BFS/DFS 有个致命缺口:蒙特卡洛树搜索(MCTS)用「随机试错+统计」让大模型想得更深,小模型 + 它竟超过 GPT-4
算法·深度优先·宽度优先
万法若空2 小时前
CSP-J/S 排序算法完整专题训练题单
数据结构·算法·排序算法
凉茶钱2 小时前
【数据结构】排序(快排,选择,直接插入,希尔)
数据结构·算法·排序算法
weixin_446260852 小时前
拆解再复用:大模型智能体的跨任务技能迁移
人工智能·深度学习·算法
Brilliantwxx2 小时前
【Linux】 进程(4)七大进程状态深度解析
linux·运维·算法
青少儿编程课堂3 小时前
用图形化编程做一个“少年探险闯关”小游戏:方向键控制、碰撞检测与多关卡串起完整项目
c++·python·算法·bfs·信息学竞赛
CQU_JIAKE3 小时前
8.22【A】
算法
二十雨辰3 小时前
[Java]-数据集合
数据结构