找出数组每个元素右边第一个比它大的元素的位置
2020.7.5
我们维护一个单调栈。保证从栈底到栈顶元素单调递减。
从右向左遍历列表
如果栈为空,则根本没有比它大的元素,记录-1
如果栈顶元素大于当前列表元素,那么记录栈顶元素为该元素对应的答案
如果栈顶元素小于等于当前列表元素,那么直接pop栈顶元素,继续比较栈顶元素和当前列表元素…
将当前列表元素插入到单调栈中。
因为我们要找的是右边第一个比它大的元素,那么越靠左,优先级就越高。
#include <bits/stdc++.h>
using namespace std;
vector<int> getRightFirstBigger(vector<int> v) {
vector<int> ans(v.size());
if(!v.size()) return ans;
int len = v.size();
stack<int> St; //单调栈,从栈底到栈顶单调递减
for(int i=len-1;i>=0;--i) { //从右向左遍历列表
while(!St.empty()) {
if(v[St.top()]<=v[i]) St.pop();
else {
ans[i] = St.top();break;
}
}
if(St.empty()||!St.empty()&&v[St.top()]<=v[i]) ans[i] = -1;
while(!St.empty()&&v[St.top()]<=v[i]) St.pop();
St.push(i);
}
return ans;
}
int main(void) {
vector<int> v = {3,6,5,4,7,8,1};
vector<int> ans = getRightFirstBigger(v);
for(int i=0;i<(int)v.size();++i) {
cout<<ans[i]<<" ";
}cout<<endl;
for(int i=0;i<(int)v.size();++i) {
if(ans[i]==-1) cout<<"-1 ";
else cout<<v[ans[i]]<<" ";
}cout<<endl;
return 0;
}
时间复杂度O(n)