数组中每个位置右边第一个比它大的数

  给定一个数组,O(N) 时间复杂度求出所有元素右边第一个大于该元素的值。

样例输入:1, 5, 3, 6, 4, 8, 9, 10, 2
样例输出:5, 6, 6, 8, 8, 9, 10, -1, -1

样例输入:8, 2, 5, 4, 3, 9, 7, 2, 5
样例输出:9, 5, 9, 9, 9, -1, -1, 5, -1

  题目的终点当然是 O(1) 时间,也就是遍历一次就应该能够输出,那一定是需要辅助空间的了,这里用到的是单调栈,栈里存放的是数组下标,数组大小和 v 一样,所有元素都初始化为 -1。
  每次遍历到数组 v 的一个位置 i,设栈顶值为 top:

  • 栈为空,i 入栈;
  • 如果v[i] <= v[top],i 入栈;
  • 如果v[i] > v[top],res[top] = v[i],栈 pop 出一个,继续迭代判断,直到 i 入栈。

  相当于,只要当前元素值大于栈顶存放索引的数组元素值,那设置右边最大值,然后 pop,继续判断。

#include 
#include 
#include 
using namespace std;

vector<int> right_larger(const vector<int>& v) {
	vector<int> res(v.size(), -1);
	stack<int> st;
	for(int i = 0; i < v.size(); ++i)	{
		while(!st.empty() && v[i] > v[st.top()]) {
			res[st.top()] = v[i];
			st.pop();
		}
		st.push(i);
	}
	return res;
}

int main() {
	auto res1 = right_larger({ 1, 5, 3, 6, 4, 8, 9, 10, 2 });
	for (const int& i : res1)
		cout << i << ' ';
	cout << endl;
	auto res2 = right_larger({ 8, 2, 5, 4, 3, 9, 7, 2, 5 });
	for (const int& i : res2)
		cout << i << ' ';
}

你可能感兴趣的:(#,编程题)