剑指offer(21):栈的压入、弹出序列
輸入兩個整數(shù)序列,第一個序列表示棧的壓入順序,請判斷第二個序列是否可能為該棧的彈出順序。假設(shè)壓入棧的所有數(shù)字均不相等。例如序列1,2,3,4,5是某棧的壓入順序,序列4,5,3,2,1是該壓棧序列對應(yīng)的一個彈出序列,但4,3,5,1,2就不可能是該壓棧序列的彈出序列。(注意:這兩個序列的長度是相等的)
?
思路:對于出棧的每一個元素,在它前面入棧的元素,要么已經(jīng)被彈出(在出棧序列中位于該元素前方),要么未被彈出且之后會被彈出(在出棧序列中位于該元素后方)。4,5,3,2,1 滿足但是4,3,5,1,2不滿足的區(qū)別是,前一個彈出序列,3出現(xiàn)的時候,2和1都未曾出現(xiàn),那2和1一定會按照? ? ?2 -> 1? ? 的順序(入棧的反向順序)出現(xiàn); 而第二個序列中1出現(xiàn)在了2的前面,所以不可能是彈出序列。
考慮每一個出棧元素(比如3),在入棧序列中的位置,以及入棧序列中在它之前的元素/在出棧序列中出現(xiàn)的順序。?入棧序列中在它之前的元素,要么出棧在它之前,要么在它之后(比如出棧序列2,3,1,4,5, 2在3前面但1在3后邊),在它之后出現(xiàn)的/所有入棧序列前端元素/一定滿足的條件是/元素在入棧序列位置越靠前,在出棧序列中位置會越靠后(反向)。
class Solution { public:bool IsPopOrder(vector<int> pushV,vector<int> popV) {if(pushV.empty()) return true;if(pushV.size() != popV.size()) return false;typedef vector<int>::iterator iterator;for(iterator val_in_pop = popV.begin(); val_in_pop != popV.end(); val_in_pop++){iterator current_object = val_in_pop;// 對每個出棧序列的元素,在入棧序列中找到其位置iterator val_in_push = find(pushV.begin(), pushV.end(), *val_in_pop);
// 如果兩個vector不包含同一個元素,那不可能是同一組數(shù)if(val_in_push == pushV.end())return false;
// 入棧序列之前有多少元素,在彈出序列中的位置大小就要比較多少次, 比如 4,5,3,2,1,對4來說, 入棧序列前面有1,2,3,就要比較三次for(int i = val_in_push - pushV.begin(); i > 0; i--){
// 每次前移一個元素,相鄰兩個元素比較iterator former_in_push = val_in_push - 1;
// 入棧序列前一個元素在出棧序列的位置iterator former_in_pop = find(val_in_pop, popV.end(), *former_in_push);
// 找不到就過,因為可能之前已經(jīng)彈出去了;找到了就要滿足反向的順序;不滿足位置關(guān)系就是錯誤的if(former_in_pop != popV.end()){if(former_in_pop - current_object > 0)current_object = former_in_pop;elsereturn false;}val_in_push--;}}return true;} };
?
轉(zhuǎn)載于:https://www.cnblogs.com/heifengli/p/11252848.html
總結(jié)
以上是生活随笔為你收集整理的剑指offer(21):栈的压入、弹出序列的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 洛谷 P3627 [APIO2009]抢
- 下一篇: Learning the Vi Edit