透過一遍單調棧找出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] << " ";
}