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;
}
相关推荐
路灯上の马陈3 小时前
数据结构-树
数据结构·1024程序员节
澳鹏Appen3 小时前
澳鹏重磅发布ExamOCRBench:面向端到端试卷判分的多任务基准
算法·benchmark·基准评测
benjormin3 小时前
Java数据结构 二叉搜索树
数据结构·算法
人工智能培训4 小时前
知识图谱:结构化表达实体与关系的知识组织技术
大数据·人工智能·算法·重构·生活·知识图谱
地平线开发者4 小时前
QAT 实战:从 PyTorch 模型到 J6E 实板精度与延时验证
pytorch·算法·自动驾驶
IT星宿4 小时前
github-gravity:用 Rapier2D 把 GitHub 贡献图做成 SVG 物理动画
算法·github
LDR0065 小时前
LDR6100 智能遥控器精品软文:Type-C 充电口与低功耗量产维护
c语言·开发语言
♡すぎ♡5 小时前
SWE 的基本条件
算法·swe·浅水模拟
郝学胜-神的一滴6 小时前
AI 编程智能体 17:四步搞定专属AI智能体
大数据·人工智能·python·神经网络·算法·langchain·强化学习
微尘hjx6 小时前
【StrongSort 03】多轨迹算法StrongSort改进点
人工智能·算法·yolo·视觉检测·ultralytics·strongsort·轨迹算法