给定一个循环数组(最后一个元素的下一个元素是数组的第一个元素),输出每个元素的下一个更大元素。数字 x 的下一个更大的元素是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你应该循环地搜索它的下一个更大的数。如果不存在,则输出 -1。
示例:
输入: [1,2,1]
输出: [2,-1,2]
解释: 第一个 1 的下一个更大的数是 2;
数字 2 找不到下一个更大的数;
第二个 1 的下一个最大的数需要循环搜索,结果也是 2。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/next-greater-element-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
单调栈
栈中存放的是元素的下标,从栈底到栈顶的元素下标对应的值是单调递减的。
例如:我们维护的数组是[5, 4, 3, 2, 7, 6, 1]。
有一点需要清楚,如何实现循环数组,当遍历数组的时候实现从前到后两次的遍历就完成了本题需要涉及的要求,例如我们当前遍历到6,需要在循环数组中找第一个比6大的元素,先从6开始向后找,发现没有,由于循环数组,我们来到了5的位置,开始向后遍历,发现7满足条件。所以我们最多只需要遍历两次数组就可以得到答案。
另一个重要的点,就是我们找5的时候发现满足比5大的第一个元素是7,而4,3,2这三个数都比5小,所以这三个数满足比它大的第一个元素也是7,所以就不用我们依次寻找4,3,2满足条件的元素了。
所以我们构建一个从栈底到栈顶单调递减的栈(单调递减指的是栈内元素的下标对应的元素是单调递减的)
对于例子[5, 4, 3, 2, 7, 6, 1]
单一从前到后第一次遍历数组为例:
先创建一个大小为n的数组res(n为nums的长度),并将初始值置-1。
我们先遍历5,此时栈为空,将5对应的下标0入栈,
遍历到4,发现4比5小,满足栈单调递减的特性,于是将4的下标1入栈。
遍历到3,发现3比4小,满足栈单调递减的特性,于是将3的下标2入栈。
遍历到2,发现2比3小,满足栈单调递减的特性,于是将2的下标3入栈。
遍历到7,发现7比2大,将2下标处的res中元素更改为7,同时将2的下标3出栈,再判断7与新的栈顶下标对应的元素的关系,如果7还比新的栈顶下标对应的元素大,那么也将res中新的栈顶下标对应的元素更改为7,直到找到新的栈顶下标对应的元素>7为止,然后将7对应的下标入栈。
class Solution {
public:
vector<int> nextGreaterElements(vector<int>& nums) {
int n=nums.size();
vector<int> res(n,-1);
stack<int> stk;
for(int i=0;i<2*n-1;i++){
while(!stk.empty()&&nums[stk.top()]<nums[i%n]){
res[stk.top()]=nums[i%n];
stk.pop();
}
stk.push(i%n);
}
return res;
}
};
当然如果你把数组给他展开,比如[1, 2, 1 ]展开之后就是[1, 2, 1, 1, 2]。这样就变成了496的思想啦~~~~~~~~~~~嘿嘿