Solution: the straightforward way is brute force, i.e, find the NGE for each element A[i] by scanning A[i+1:]. The time and space complexities of this method are O(N^2) and O(1) respectively. The more elegant way is to employ a stack. The basic idea is processing each element A[i] one by one by following the rules below:
- If the stack is empty, simply push index i into stack;
- If not, compare A[i] and the element of A with index of top-most element, say s, of the stack, i.e., A[s]:
- If A[s] \ge A[i], simply push i into stack;
- If A[s]<A[i], then it means that A[i] is NGE of A[s], thus we pop s, and repeatedly process the rest elements of stack until we got A[s] \ge A[i] or stack become empty; then we push i into stack.
#include<iostream>
#include<stack>
#include<vector>
#include<ctime> //time()
#include<cstdlib> //srand() and rand()
std::vector<int> nextLargerEle(std::vector<int> arr){
if(arr.size()<=1)
return arr;
std::vector<int> ret(arr.size(), 0);
std::stack<int> s;
for(size_t i=0; i<arr.size(); ++i){
while(!s.empty()&&arr[s.top()]<arr[i]){
ret[s.top()]=arr[i];
s.pop();
}
s.push(i);
}
while(!s.empty()){
ret[s.top()]=arr[s.top()];
s.pop();
}
return ret;
}
int main(){
std::vector<int> ret;
ret.reserve(10);
srand(time(NULL));
for(int i=0; i<10; ++i)
ret.push_back(rand()%9);
std::cout<<"Input: ";
for(size_t i=0; i<ret.size(); ++i)
std::cout << ret[i] <<" ";
std::cout<< std::endl;
ret = nextLargerEle(ret);
std::cout<<"Output: ";
for(size_t i=0; i<ret.size(); ++i)
std::cout << ret[i] <<" ";
std::cout<< std::endl;
return 0;
}
No comments:
Post a Comment