个人练习-Leetcode-2454. Next Greater Element IV

题目链接:https://leetcode.cn/problems/next-greater-element-iv/

题目大意:给出一串数列nums[],要求给出每个元素对应的【在其右边的】【第二个】【比它大的元素】,如果这个值不存在,填上-1

思路:暴力做肯定会超时,刚开始想着从后往前做(因为倒数两个元素对应的值肯定是-1),但发现元素并没有被排过序,需要维护的东西有点多。不愧是困难题…

看了题解才知道要用单调栈做。并且思路清奇。单调栈中存放的是元素的下标。需要维护两个单调递减的栈:

  • s0:表示里面的元素的右边没有比它大的
  • s1:表示里面的元素的右边有一个比它大的

每次扫描到nums[i],首先将其与s1栈顶的元素对比,如果nums[i]更大,说明nums[i]就是【右边的】【第二个】【比它大的元素】,栈顶元素弹出,填入答案。这个过程应该是个while循环,保证所满足上述情况的栈顶元素都被弹出。

            while(!s1.empty() && nums[i] > nums[s1.back()]) {
                answer[s1.back()] = nums[i];
                s1.pop_back();
            }

再将其与s0栈顶元素对比,如果nums[i]更大,说明栈顶元素现在【右边有一个比它大的】,要将其移到s1中了。弹出。同样while循环到所有满足上述情况的栈顶元素都被弹出。这些被弹出的元素保存在临时数组to_move[]里,随后保持单调性移动到s1中。

            while(!s0.empty() && nums[i] > nums[s0.back()]) {
                to_move.push_back(s0.back());   
                s0.pop_back();
            }

            for (int j = to_move.size()-1; j >= 0; j--)
                s1.push_back(to_move[j]);

扫描完后,将当前元素【的下标】塞进s0中(因为它右边还未扫描,还没有任何东西,因此肯定是属于s0的)

            s0.push_back(i);

完整代码

class Solution {
public:
    vector<int> secondGreaterElement(vector<int>& nums) {
        int n = nums.size();
        vector<int> answer(n, -1);
        vector<int> s0, s1;

        for (int i = 0; i < n; i++) {
            vector<int> to_move;
            while(!s1.empty() && nums[i] > nums[s1.back()]) {
                answer[s1.back()] = nums[i];
                s1.pop_back();
            }
            while(!s0.empty() && nums[i] > nums[s0.back()]) {
                to_move.push_back(s0.back());   
                s0.pop_back();
            }

            for (int j = to_move.size()-1; j >= 0; j--)
                s1.push_back(to_move[j]);
            
            s0.push_back(i);
        }


        return answer;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值