單調棧模板

台州第一深情發表於2024-07-24

透過一遍單調棧找出i下標數字左右兩邊第一個比它大的數字
在將數放入棧的時候,將她與棧頂比較,因為棧是先進後出,所以當棧頂的數比她小的時候,就壓出棧頂,並且對於棧頂來說,這個數就是她左邊第一個比它大的數,當這個數遇到比它大的數時,這個比它大的數就是它右邊第一個大於它的數,最後再將棧中遺留的數重複上面判斷即可

點選檢視程式碼
stack<int> st;
int ansl[N]; // 左邊的
int ansr[N]; // 右邊的
int main()
{
	int n;
	cin >> n;
	for (int i = 1; i <= n; i++)
	{
		cin >> a[i];
	}
	for (int i = n; i >= 1; i--) // 我是從右往左找
	{
		while (!st.empty() && a[i] >= a[st.top()]) // 噹噹前的棧不為空,並且當前下標的數值一直大於棧頂的數值,就彈出棧頂
		{
			int p = st.top(); // 記錄棧頂
			st.pop();
			ansl[p] = i;   // 對於每個被彈出的棧頂,將它彈出的這個值就是它左邊的第一個比它大的數
			if (st.size()) // 棧頂被彈出後如果還有值,那對於彈出的棧頂來說,被彈出後的棧的棧頂就是它右邊的第一個比它大的數
				ansr[p] = st.top();
		}
		if (st.empty()) // 如果棧為空,說明當前這個數比之前壓進去的所有數都要大,她右邊沒有比他大的數
		{
			ansr[i] = 0;
		}
		else
		{
			ansr[i] = st.top(); // 不然,當前棧頂就是她右邊第一個比她大的數
		}
		st.push(i); // 壓入棧
	}
	while (st.size()) // ,說明棧中還有值,需要彈出,彈出的數的左邊沒有比它大的數
	{
		int p = st.top();
		st.pop();
		if (st.size())//對於每個被彈出的數,如果棧中還有數字,那棧頂的數就是她後邊第一個比她大的數
			ansr[p] = st.top();
	}
	for (int i = 1; i <= n; i++)
	{
		cout << ansr[i] << " ";
	}

相關文章