1. 程式人生 > >順序進棧亂序出棧的所有可能順序之演算法

順序進棧亂序出棧的所有可能順序之演算法

題目:設有編號為1,2,3,4的四輛列車,順序進入一個棧式結構的車站,具體寫出這四輛 列車開出車站的所有可能的順序。
今天看到這個資料結構練習題,一開始認為只有窮舉然後驗證的方法。
習題後面給出的答案:
至少有14種。
①全進之後再出情況,只有1種: 4,3,2,1
②進3個之後再出的情況,有3種,3,4,2,1 3,2,4,1 3,2,1,4
③進2個之後再出的情況,有5種,2,4,3,1 2,3,4,1 2,1,3,4 2,1,4,3 2,3,1,4
④進1個之後再出的情況,有5種,1,4,3,2 1,3,2,4 1,3,4,2 1,2,3,4 1,2,4,3

1-4的所有排列組合有n=4!=24種,然後我們需要依照下面的規律進行篩檢:
例3,4,2,1
3後面比3小的數字有1和2,那麼出棧的順序必然是2,1,倒序排列
4後面比4小的是2和1,倒序
2後面比2小的是1,不需要檢查
1是最後一個也不需要檢查
上面所有的序列都滿足上述的規律
如果是3,4,1,2,明顯可以檢查到時序列是不符合實際,錯誤的。
然後如果通過程式碼實現,光排列組合時間複雜度就需要O(n!),而篩檢是否合適也幾乎是O(n!),最終的時間複雜度幾乎是O(n! * n!)。在n數值較大時幾乎是不現實的。
我分析了規律,通過遞迴的方式進行了優化,簡化到O(n*n)。

當n=1時,只有k(k=1)種可能;
n=1 序列中位置 k 對下一編號的影響
a 1

當n=2時,可以將編號2的列車插到編號1的列車的兩邊,(a)1(b);
n=2 序列中位置 k 對下一編號的影響
a 1
b 1 (a, 1):表示編號3列車插在a位置時有1種序列需要排除
(a):插到a位置時序列號為2,1,有1種可能。因為是倒序,所以下一次編號3列車放到任何位置都是可以的。
(b):插到b位置時序列號為1,2,有1種可能。下次3列車插到a位置是不可以的。
故整理得,n=2時排列組合有2種;
編號3列車(a)x(b)y(c),在放到(a)時,有1種序列不合理。

當n=3時,編號3列車有3個位置可以插入,(a)x(b)y(c)。
n=3 序列中位置 k 對下一編號的影響
a 2-1=1
b 2 (a, 2):表示編號4列車插在a位置時有2種序列需要排除
c 2 (a-b, 2):表示編號4列車插在a位置時有2種序列需要排除且
插在b位置時有2種序列需要排除
故整理得,n=3時排列組合有1+2+2=5種;
編號4列車(a)x(b)y(c)z(d),在放到(a)時,有2+2=4種序列不合理,
在放到(b)時,有2種序列不合理。

當n=4時,編號4列車有4個位置可以插入,(a)x(b)y(c)z(d)。
n=4 序列中位置 k 對下一編號的影響
a 5-4=1
b 5-2=3 (a, 3)
c 5 (a-b, 5)
d 5 (a-c, 5)
故整理得,n=4時排列組合有1+3+5+5=14種;
編號5列車(a)x(b)y(c)z(d)m(e),
在放到(a)時,有3+5+5=13種序列不合理,
在放到(b)時,有5+5=10種序列不合理,
在放到(c)時,有5種序列不合理。
求出的值和窮舉的是一樣的。

當n=5時,編號5列車有5個位置可以插入,(a)x(b)y(c)z(d)m(e)。
n=5 序列中位置 k 對下一編號的影響
a 14-13=1
b 14-10=4 (a, 4)
c 14-5=9 (a-b, 9)
d 14 (a-c, 14)
e 14 (a-d, 14)
故整理得,n=5時排列組合有1+4+9+14+14=42種;
編號6列車(a)x(b)y(c)z(d)m(e)n(f),
在放到(a)時,有4+9+14+14=41種序列不合理,
在放到(b)時,有9+14+14=37種序列不合理,
在放到(c)時,有14+14=28種序列不合理,
在放到(d)時,有14種序列不合理。