算法初学者(单调栈)

单调栈:栈中的元素是严格单调递增或者递减的,也就是说:从栈底到栈顶,元素的值逐渐增大或者减小,多用于求解元素的左右大小边界问题:

1:向左找第一个比自身大的数  2:向左找第一个比自身小的数。                                                    3:向右找第一个比自身大的数  4:向右找第一个比自身小的数。

使得其单调的操作(以底到顶递增为例):如果新的元素比栈顶的元素大,就入栈,小,就把栈内元素弹出来,直到栈顶元素比新元素小再入栈。

元素间大小判断(以底到顶递增为例):1当栈中已有元素需要出栈时(遇见了比它小的新元素),说明后续这个新元素是需要出栈的元素向后找第一个比其小的元素。                                    2当元素出栈后,新栈顶元素是出栈元素向前找第一个比其小的元素。

例题洛谷P5788

思路:求每个数后第一个大于他的数

从后往前扫,对于每个元素:1弹出栈顶比他小的元素,2此时栈顶就是答案(放入应该数组),3加入这个元素。

#include
#include
#include
#include
using namespace std;
int n;
int a[3000005], f[3000005];
stacks;//栈,存储下标
int main() {
	cin >> n;
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
	}
	//a[i]入栈之前:
	//1.栈顶>a[i],栈顶元素就是第一个大于a[i]的元素
	//2.栈顶= 1; i--) {
		while (!s.empty() && a[s.top()] <= a[i]) {
			s.pop();
		}
		if (s.empty() == 1) {
			f[i] = 0;
		}
		else {
			f[i] = s.top();
		}
		//f[i] = (s.empty() == 1) ? 0 : s.top();
		s.push(i);
	}
	for (int i = 1; i <= n; i++) {
		cout << f[i] << " ";
	}
	cout << endl;

	return 0;
}

对不起,这个有点超时。涉及一个小知识。(输入和输出)

cin和cout使得这题TLE,但是改成scanf和printf后就行了之前文章有所提及

总结输入数据多就想着用scanf和printf。以后改了,少用cin和cout了。

你可能感兴趣的:(c++,算法)