算法-驗證棧序列
1、驗證棧序列
給定 pushed 和 popped 兩個序列,每個序列中的 值都不重複,只有當它們可能是在最初空棧上進行的推入 push 和彈出 pop 操作序列的結果時,返回 true;否則,返回 false 。
示例 1:
輸入:pushed = [1,2,3,4,5], popped = [4,5,3,2,1]
輸出:true
解釋:我們可以按以下順序執行:
push(1), push(2), push(3), push(4), pop() -> 4,
push(5), pop() -> 5, pop() -> 3, pop() -> 2, pop() -> 1
示例 2:
輸入:pushed = [1,2,3,4,5], popped = [4,3,5,1,2]
輸出:false
解釋:1 不能在 2 之前彈出。
提示:
0 <= pushed.length == popped.length <= 1000
0 <= pushed[i], popped[i] < 1000
pushed 是 popped 的排列。
這道題可以說是非常經典的題目了,很好的考查了棧的性質。我們可以模擬入棧和出棧來解決這個問題。
我們怎麼模擬呢?顯然,窮舉法可以做到模擬所有情況,算法時間複雜度爲O(N!)。這不是我們希望的。
那我麼可以想一下,如果要出棧,那必然要先入棧,所以,第一步,我們需要進行入棧操作,但顯然,我們不能一直入棧,我們必須要根據一定的條件終止入棧(棧頂等於出棧棧的棧頂),然後出棧(棧頂等於出棧棧的棧頂,直到不相等),當所有元素入棧完成之後,我們判斷一下出棧元素是不是等於入棧元素的數量,如果相等,那證明出棧序列是可以做到的,因爲每個元素最多隻被遍歷一次和彈出一次,因此,時間複雜度爲O(N)。
下面用代碼實現上面描述的過程
public boolean validateStackSequences(int[] pushed, int[] popped) {
Stack<Integer> stack=new Stack<Integer>();//輔助棧
int ptrPop=0;//指向出棧數組的棧頂
for(int in:pushed){
stack.push(in);
while(!stack.isEmpty()&&ptrPop<popped.length&&stack.peek()==popped[ptrPop]){
ptrPop++;
stack.pop();
}
}
return ptrPop==popped.length;
}