题目:给定一个整型数组,数组元素随机无序的,要求打印出所有元素右边第一个大于该元素的值。如果不存在,对应值设为-1即可。
如数组A=[1,5,3,6,4,8,9,10] 输出[5, 6, 6, 8, 8, 9, 10, -1]
如数组A=[8, 2, 5, 4, 3, 9, 7, 2, 5] 输出[9, 5, 9, 9, 9, -1, -1, 5, -1]
首先暴力法就不用说了,两层遍历就可以。
不过这种题目是典型的单调栈的思路,可以一次遍历就得出所有结果。
用栈来保存未找到右边第一个比它大的元素的索引(很多单调栈存储的都是索引值),初始栈里放的是第一个元素的索引0。
然后遍历数组,假设当前元素为nums[i],此时有两种情况:
-
nums[i] > nums[stk.top()]
那么元素nums[i]就是索引为stk.top()的元素的右边第一个大于它的值:res[stk.top()] = nums[i],stk.pop(); -
nums[i] <= nums[stk.top()]
不作处理
最后无论是哪种情况,处理完都将当前下标i入栈。
代码:
#include <iostream>
#include <stack>
#include <vector>
using namespace std;
int main(){
int n;
cin >> n;
vector<int> nums(n), res(n, -1);
for(int i = 0; i < n; ++i) cin >> nums[i];
stack<int> s;//存储的是下标
s.push(0);//下标0
for(int i = 1; i < n; ++i){
while(!s.empty() && nums[s.top()] < nums[i]){//此处是while循环
res[s.top()] = nums[i];
s.pop();
}
s.push(i);
}
for(const auto &c : res) cout << c << " ";
cout << endl;
return 0;
}