【LeetCode496】下一个更大元素 I(单调栈)

举报
野猪佩奇996 发表于 2022/01/23 00:23:48 2022/01/23
【摘要】 一、题目 提示: 1 <= nums1.length <= nums2.length <= 10000 <= nums1[i], nums2[i] <= 104nums...

一、题目

在这里插入图片描述
提示:

  • 1 <= nums1.length <= nums2.length <= 1000
  • 0 <= nums1[i], nums2[i] <= 104
  • nums1和nums2中所有整数 互不相同
  • nums1 中的所有整数同样出现在 nums2 中

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

二、思路

单调栈就是用于解决 Next Greater Number 问题。

单调栈模板如下,首先下面版本的前提条件(可灵活改动)是找出nums数组中每个元素,对应的右边的第一个更大的元素值。我们利用一个辅助栈stack,从nums数组的最右边开始倒着遍历:

(1)每遍历到当前的元素A,将其和栈顶元素值比较大小,如果栈顶元素值小(矮子去掉)则pop掉,直到出现一个比A大的栈顶元素B;
(2)B即当前元素的res值。
(3)将A入栈,循环以上操作。

vector<int> nextGreaterElement(vector<int>& nums) {
    vector<int> res(nums.size()); // 存放答案的数组
    stack<int> s;
    // 倒着往栈里放
    for (int i = nums.size() - 1; i >= 0; i--) {
        // 判定个子高矮
        while (!s.empty() && s.top() <= nums[i]) {
            // 矮个起开,反正也被挡着了。。。
            s.pop();
        }
        // nums[i] 身后的 next great number
        res[i] = s.empty() ? -1 : s.top();
        // 
        s.push(nums[i]);
    }
    return res;
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

时间复杂度分析:虽然for内嵌套while循环,但是时间复杂度不是 O ( n 2 ) O(n^2) O(n2),而是 O ( n ) O(n) O(n),因为从整理看,n个元素每个元素都被push入栈一次,最多也会被pop出栈一次,总体计算规模和元素个数n成正比。

而本题就可以直接对nums2用单调栈模板,因为nums1nums2的子集,去后者得到的答案里找就行。
具体的找法:nums2每个元素的答案都记录在res1里,为了方便nums1直接获取,借助一个哈希表map。

三、代码

方法一:暴力两层for循环(显然时间效率很低)。

class Solution {
public:
    vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
        vector<int>ans;
        bool flag = false;
        for(int i = 0; i < nums1.size(); i++){
            int num = nums1[i];
            for(int j = 0; j < nums2.size(); j++){
                if(nums2[j] == num){
                    flag = true;
                    //continue;
                }
                if(flag && nums2[j] > num){
                    ans.push_back(nums2[j]);
                    break;
                }else if(j == nums2.size()-1 && nums2[j] <= num){
                    ans.push_back(-1);
                    break;
                }
            }
            num = 0;
            flag = false;
        }
        return ans;
    }
};

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

在这里插入图片描述
方法二:单调栈

class Solution {
public:
    vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
        vector<int> res1(nums2.size());
        vector<int> res2;
        map<int, int>mp;
        stack<int>s;
        for(int i = nums2.size() - 1; i >= 0; i--){
            while(!s.empty() && s.top() <= nums2[i]){
                //把矮个子全部去掉
                s.pop();
            }
            res1[i] = s.empty()? -1: s.top();
            mp.insert(make_pair(nums2[i], res1[i]));
            s.push(nums2[i]);
        }
        for(int j = 0; j < nums1.size(); j++){
            res2.push_back(mp[nums1[j]]);
        }
        return res2;
    }
};

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

在这里插入图片描述

文章来源: andyguo.blog.csdn.net,作者:山顶夕景,版权归原作者所有,如需转载,请联系作者。

原文链接:andyguo.blog.csdn.net/article/details/122569590

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。