單調棧結構(進階) 牛客網
阿新 • • 發佈:2021-02-03
技術標籤:程式設計師面試指南188
題目描述
給定一個不含有重複值的陣列 arr,找到每一個 i 位置左邊和右邊離 i 位置最近且值比 arr[i] 小的位置。返回所有位置相應的資訊。
輸入描述:
第一行輸入一個數字 n,表示陣列 arr 的長度。
以下一行輸出 n個數字,表示陣列的值。
輸出描述:
輸出n行,每行兩個數字 L 和 R,如果不存在,則值為-1,下標從0開始。
示例1
輸入
複製
7
3 4 1 5 6 2 7
輸出
複製
-1 2
0 2
-1 -1
2 5
3 5
2 -1
5 -1
思路:首先構成一個單調棧,放入元素是有3種情況:
(1)棧為空,直接放入
(2)棧不為空,且棧頂元素大於當前放入元素,彈出棧頂元素,繼續判斷屬於那種情況
將所有元素放入後,此時棧是一個從上到下逐漸遞減的排列,依次彈出即可。具體細節見程式碼。
關於,這道題的進階,放入元素中出現了重複元素,此時單調棧中存放的不再是單一的元素,而是一個list連結串列,導論情況大致相同,只是,多一種等於棧頂元素時,放入當前棧頂連結串列。細節見程式碼,主要難點時stack,與list的配合使用。
#include<stdio.h>
#include<stack>
using namespace std;
stack<int> stack_1;
int arr[ 1000007];
int left[1000007];
int right[1000007];
int main()
{
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d",&arr[i]);
for(int i=0;i<n;i++)
{
while( !stack_1.empty() && arr[ stack_1.top() ]>arr[i] )
{
int x=stack_1.top();
stack_1. pop();
right[x]=i;
left[x]= stack_1.empty()? -1:stack_1.top();
}
stack_1.push(i);
}
//現在是一個單調棧,需要將棧中的元素清除
while( !stack_1.empty() )
{
int x=stack_1.top();
stack_1.pop();
right[x]=-1;
left[x]=stack_1.empty() ? -1:stack_1.top();
}
for(int i=0;i<n;i++)
printf("%d %d\n",left[i],right[i]);
return 0;
}
題目描述
給定一個可能含有重複值的陣列 arr,找到每一個 i 位置左邊和右邊離 i 位置最近且值比 arr[i] 小的位置。返回所有位置相應的資訊。
輸入描述:
第一行輸入一個數字 n,表示陣列 arr 的長度。
以下一行輸入 n 個數字,表示陣列的值
輸出描述:
輸出n行,每行兩個數字 L 和 R,如果不存在,則值為 -1,下標從 0 開始。
示例1
輸入
複製
7
3 4 1 5 6 2 7
輸出
複製
-1 2
0 2
-1 -1
2 5
3 5
2 -1
5 -1
#include<stdio.h>
#include<stack>
#include<list>
using namespace std;
stack< list<int> > stack_1;
list<int>::iterator it;
int arr[1000007];
int left[1000007];
int right[1000007];
int main()
{
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d",&arr[i]);
for(int i=0;i<n;i++)
{
// it=stack_1.top().begin();
while( !stack_1.empty() && arr[ *(stack_1.top().begin() ) ]>arr[i] )
{
list<int> mylist;
for( it=stack_1.top().begin(); it!=stack_1.top().end() ; it++ )
mylist.push_back( *it );//賦值把stack_1.top賦值到mylist中
stack_1.pop();
for( it= mylist.begin() ; it!=mylist.end() ; it++ )
{
right[ *it ]=i;
left[ *it ]= stack_1.empty() ? -1 : *( --stack_1.top().end() );
}
}
if( !stack_1.empty() && arr[ *(stack_1.top().begin() ) ]==arr[i] )//當前放入元素和隊首相等
{
stack_1.top().push_back( i );
}
else
{
list<int> mylist2;
mylist2.push_back( i );
stack_1.push( mylist2 );
}
}
//此時是一個單調棧結構
while( !stack_1.empty() )
{
list<int> mylist3;
for( it=stack_1.top().begin() ; it!=stack_1.top().end() ; it++ )
mylist3.push_back( *it );
stack_1.pop();
for( it=mylist3.begin() ; it!=mylist3.end() ; it++ )
{
right[ *it ]=-1;
left[ *it ]= stack_1.empty() ? -1 : *( --stack_1.top().end() );
}
}
for(int i=0;i<n;i++)
printf("%d %d\n",left[i],right[i]);
return 0;
}