leetcode 503.下一个更大元素II
题干
给定一个循环数组(最后一个元素的下一个元素是数组的第一个元素),输出每个元素的下一个更大元素。数字 x 的下一个更大的元素是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你应该循环地搜索它的下一个更大的数。如果不存在,则输出 -1。
示例 1:
输入: [1,2,1]
输出: [2,-1,2]
解释: 第一个 1 的下一个更大的数是 2;
数字 2 找不到下一个更大的数;
第二个 1 的下一个最大的数需要循环搜索,结果也是 2。
注意: 输入数组的长度不会超过 10000。
题解
嗯是写了一个比暴力还复杂的写法,拿空间换空气。
直接超时。
class Solution {
public:
vector<int> nextGreaterElements(vector<int>& nums) {
vector<int> ans;
int n = nums.size();
if(n == 0) return ans;
deque<int> D;
stack<int> S;
ans.resize(n);
for(int i = 0 ; i < n ; ++i){
D.push_back(nums[i]);
}
for(int i = 0 ; i < n ; ++i){
while(!D.empty() && D.front() <= nums[i]){
S.push(D.front());
D.pop_front();
}
if(D.empty()) ans[i] = -1;
else ans[i] = D.front();
while(S.size() > 1){
D.push_front(S.top());
S.pop();
}
if(!S.empty()) S.pop();
D.push_back(nums[i]);
}
return ans;
}
};
单调栈的写法,两个核心,通过下标取余来遍历nums两次:
因为题目循环数组的性质,对于每个数来说,下一个更大的数可能出现在左侧也可能出现在右侧,而单调栈的写法是从左向右遍历的,遍历数组两遍来确保答案。
还有单调栈中储存下标,使得对应元素不减:
一旦栈顶对应的元素小于当前元素,就说明当前元素就是栈顶元素的下一个更大元素,此时将栈顶元素抛出,并更新栈顶下标对应的答案。
class Solution {
public:
vector<int> nextGreaterElements(vector<int>& nums) {
vector<int> ans;
int n = nums.size();
if(n == 0) return ans;
stack<int> S;
ans.resize(n,-1);
for(int i = 0 ; i < 2 * n ; ++i){
//条件判断是小于而非小于等于,因为在抛出栈中元素时会对答案进行更新,即栈顶元素在小于当前元素时才会更新(因为题目求的是下一个更大元素)
while(!S.empty() && nums[S.top()] < nums[i % n]){
ans[S.top()] = nums[i % n];
S.pop();
}
S.push(i % n);
}
return ans;
}
};