• Leetcode每日一题 503.下一个更大元素II


    给定一个循环数组(最后一个元素的下一个元素是数组的第一个元素),输出每个元素的下一个更大元素。数字 x 的下一个更大的元素是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你应该循环地搜索它的下一个更大的数。如果不存在,则输出 -1。

    示例 1:

    输入: [1,2,1]
    输出: [2,-1,2]
    解释: 第一个 1 的下一个更大的数是 2;
    数字 2 找不到下一个更大的数;
    第二个 1 的下一个最大的数需要循环搜索,结果也是 2。
    注意: 输入数组的长度不会超过 10000。

    本题可以使用单调栈在O(n)复杂度下解决。

    分析题意,可以知道我们要找到每一个数之后第一个大于它的数,那么我们可以建立一个单调递减栈,遍历输入数组,设当前即将入栈的数为nums[i],判断当前栈顶的数是否小于nums[i],如果小于,则弹出栈顶元素,并且在结果数组里给相应位置赋值nums[i],继续判断,直到栈内元素都小于nums[i],然后入栈。

    先看代码:

    class Solution {
    public:
        vector<int> nextGreaterElements(vector<int>& nums) {
            int nums_len = nums.size();
            stack<int> s;
            vector<int> res(nums_len,-1);
            
            for(int i = 0 ; i < nums_len * 2 - 1 ; i++)
            {
                while(!s.empty()&&nums[s.top()]<nums[i%nums_len]){
                    res[s.top()] = nums[i%nums_len];
                    s.pop();
                }
                s.push(i%nums_len);
            }
            return res;
        }
    };

    思考过程:

    分析while,可以发现第一个元素是直接跳过while,直接入栈的,而且保存在栈内的不是元素大小,而是元素在nums中的下标,又由于是循环数组,所以取了模。

    分析例子[1,2,1]

    当 i = 0 时,因为栈为空,while直接跳过,s.push(0%nums_len) 此时 s = [0] ; res = [-1,-1,-1];

    当 i = 1 时,因为nums[s.top()] 也就是nums[0] 小于 nums[1%nums_len] 也就是nums[1] ,所以 res[0] = nums[1] = 2; 此时 s = [ 1 ] , res = [2,-1,-1];

    当 i = 2 时,因为nums[s.top()]也就是nums[1] 等于 nums[2] ,所以此时 s = [1,2] , res = [2,-1,-1] ;

    当 i = 3 时,因为nums[s.top()]也就是nums[2] 等于 nums[3%nums_len] 也就是nums[0] 所以此时 s= [1,2,0] ,res = [2,-1,-1] 

    当 i = 4 时,因为nums[s.top()]也就是nums[0] 小于nums[4%nums_len] 也就是nums[1] ,所以res[s.top()] = res[0] = nums[1] = 2 ;  此时s = [1,2],res = [2,-1,-1];

          然后继续循环,因为res[2] 小于 nums[1] ,所以res[2] = nums[1] = 2; 此时 s = [1] , res = [2,-1, 2];

    ...

    暴力法也写了:

    class Solution {
    public:
        vector<int> nextGreaterElements(vector<int>& nums) {
            int nums_len = nums.size();
            vector<int> ans;
            for(int i = 0 ; i < nums_len ; i++)
            {
                int ind = i;
                int maxn = -1;
                int flag = 1;
                for(int j = ind ; j < nums_len ; j++)
                {
                    if(nums[j] > nums[i])
                    {
                        maxn = nums[j];
                        flag = 0;
                        break;
                    }
                }
                if(flag){
                    for(int j = 0 ; j < ind ; j++)
                    {
                        if(nums[j] > nums[i])
                        {
                            maxn = nums[j];
                            break;
                        }
                    }
                }
                ans.push_back(maxn);
            }
            return ans;
        }
    };
  • 相关阅读:
    暑假集训Day1 整数划分
    暑假集训day1 水题 乘法最大
    暑假集训Day0
    【不知道什么专题】——历年几道难题的分析。
    开发语言之我见
    选择器IDEA Maven不见了
    js 里函数调用之call
    js 闭包 匿名函数 JavaScript的IIFE(即时执行方法)immediately-invoked function expression
    ideal-check项目
    浏览器内部工作原理
  • 原文地址:https://www.cnblogs.com/xiangqi/p/14492510.html
Copyright © 2020-2023  润新知