問題描述:對於n個元素(1到n)。給定兩個n的全排序列s1,s2。其中s1為入棧順序,是2為出棧順序。問:對於s1的入棧順序,能否經過若干的出入棧操作,使得出棧順序恰為s2。是輸出yes,否輸出no。
思路:由於只有乙個棧,很容易得出s1到s2的操作序列是唯一的,因此可以用模擬法。遍歷s2的每個元素。
for(遍歷s2的每乙個元素)
}但是這樣的思路在實現上還是有些複雜,如判斷在**的步驟要遍歷陣列,不僅增加複雜度,還影響到**的編寫,因此先做一下變換,「固定」輸入順序。
一建立對映,簡化問題:
由於輸入,輸出序列的都是不確定的狀態,因此給問題的解決帶來一定的難度,此時我們發現n個元素恰為1到n,可以通過乙個對映關係「固定」某乙個序列,很自然的想到「元素---位置」這一對映,這樣可以把輸入序列變為s0(1,2,3...n),此時輸出序列變為s2.那麼這一對映又是怎樣實現的呢?其實,還是非常簡單的。舉乙個例子:(為了區別,元素採用中文,位置用數字表示,一共有6個元素)
要解決的問題:
輸入順序:五,三,二,一,六,四。
輸出順序:三,六,二,四,五,一。
對於對映後的輸入順序已經是固定了,即是1,2,3,4,5,6。那麼輸出順序應該變為什麼呢?此時,在輸入順序:三是第2個元素,六是第5個元素,二是第3個元素。。。所以輸出順序應該是2,5,3,6,1,4。代表要輸出順序依次為:(按輸入順序)第2個元素,也就是三,第5個元素,也就是六。。。**實現如下:
for(i=1;i<=n;i++)
}}
此時a陣列也是n的乙個全排序。
此時,問題就變為從s0(1,2,3,...n)到a的乙個操作。
入棧順序從小到大,用min表示還沒有入棧元素的最小值,表示min~n這些數還沒有入棧。。。按照上面的思路**如下:
min=1;
res=true;
for(i=1;i<=n;i++)elseelse
s.pop(); }}
if(res)
printf("yes\n");
else
printf("no\n");
出棧序列的合法性 模擬
7 15 出棧序列的合法性 25 分 給定乙個最大容量為 m 的堆疊,將 n 個數字按 1,2,3,n 的順序入棧,允許按任何順序出棧,則哪些數字序列是不可能得到的?例如給定 m 5 n 7,則我們有可能得到,但不可能得到。輸入格式 輸入第一行給出 3 個不超過 1000 的正整數 m 堆疊最大容量...
判斷出入棧的合法性
本篇部落格闡述內容 假設入棧序列是 出棧序列是 那麼我們讓入棧序列入棧,1先入,看一看第乙個出棧的是不是1,不是繼續將2壓棧,直到1,2,3,4入棧,4和出棧序列的第乙個匹配到了,我們將入棧的 4 pop掉,然後繼續和出棧序列的第二個匹配,看看是否需要出棧,如不需要,繼續壓棧,以此類推,直到入棧序列...
出棧序列的合法性
給定乙個最大容量為 m 的堆疊,將 n 個數字按 1,2,3,n 的順序入棧,允許按任何順序出棧,則哪些數字序列是不可能得到的?例如給定 m 5 n 7,則我們有可能得到,但不可能得到。輸入格式 輸入第一行給出 3 個不超過 1000 的正整數 m 堆疊最大容量 n 入棧元素個數 k 待檢查的出棧序...