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;
    }
};
原文地址:https://www.cnblogs.com/xiangqi/p/14492510.html