31:棧的壓入、彈出序列

題目31:棧的壓入、彈出序列

輸入兩個整數序列,第一個序列表示棧的壓入順序,請判斷二個序列是否為該棧的彈出順序。假設壓入棧的所有數字均不相等。

舉例說明

序列1,2,3,4,5是某棧的壓入順序,序列4,5,3,2,1是該壓棧序列對應的一個彈出序列,但4,3,5,1,2就不可能是該壓棧序列的彈出序列。(注意:這兩個序列的長度是相等的)

思路

解決這個問題很直觀的想法就是建立一個輔助棧,把輸入的第一個序列中的數字依次壓入該輔助棧,并按照第二個序列的順序依次從該棧中彈出數字。

判斷一個序列是不是棧的彈出序列的規(guī)律:

  • 壓棧序列:int[] push
  • 彈出序列:int[] pop
  • 輔助棧:Stack<Integer> help = new Stack<>();
  • 判斷彈出元素是不是棧頂元素
    help.peek() != pop[nextPop]
  1. 如果Stack下一個彈出的數字剛好是棧頂數字,那么直接彈出
  2. 如果Stack下一個彈出的數字不在棧頂,把push[]中還沒有入棧的數字壓入help,直到把下一個需要彈出的數字壓入棧頂為止
  3. 如果所有的數字都壓入棧了仍然沒有找到下一個彈出的數字,那么該序列不可能是一個彈出序列

代碼實現

public class _31 {
    public static boolean isPopOrder(int[] push, int[] pop) {
        boolean isPossible = false;
        // a. 都不為空 b. 都有數據,且數據個數都相等
        if (push != null && pop != null && push.length > 0 && push.length == pop.length) {
            Stack<Integer> help = new Stack<>();// 用于存放入棧時的數據
            int nextPush = 0;
            int nextPop = 0;

            while (nextPop < pop.length) { // 如果pop[] 沒有處理完就繼續(xù)進行處理
                // a. 棧為空 b. 棧頂的元素與當前處理的出棧元素不相同
                while (help.isEmpty() || help.peek() != pop[nextPop]) {
                    if (nextPush >= push.length) {//若入棧的元素已經全部入棧了
                        break;//就退出內層循環(huán)
                    }
                    //說明沒被break。nextPush < push.length,還有push[] 可以入棧
                    help.push(push[nextPush]);// 將push[]元素 入 help棧
                    nextPush++;// 指向下一個要處理的入棧元素的位置
                }
                // 執(zhí)行到此處有兩種情況:
                // 第一種:在棧頂上找到了一個與入棧元素相等的元素
                // 第二種:在棧頂上沒有找到一個與入棧元素相等的元素,但輸入棧的元素已經全部入棧了
                // 對于第二種情況就說彈出棧的順序是不符合要求的,退出外層循環(huán)
                if (help.peek() != pop[nextPop]) {
                    break;
                }
                help.pop();// 對應到第一種情況:需要要棧的棧頂元素彈出
                nextPop++;// 指向pop[]下一個要處理的出棧元素的位置
            }

            // 執(zhí)行到此處有兩種情況
            // 第一種:外層while循環(huán)被break
            // 第二種:所有的出棧元素都被正確匹配

            // 對于出現的第一種情況其stack.isEmpty()必不為空,原因為分析如下:
            // 所有的入棧元素一定會入棧,但是只有匹配的情況下才會出棧,
            // 匹配的次數最多與入棧元素個數元素相同(兩個數組的長度相等),如果有不匹配的元素,
            // 必然會使出棧的次數比入棧的次數少,這樣棧中至少會有一個元素
            // 對于第二種情況其stack.isEmpty()一定為空
            // 所以書本上的nextPop == pop.length(pNextPop-pPop==nLength)是多余的
            if (help.isEmpty()) {
                isPossible = true;
            }
        }
        return isPossible;
    }

    public static void main(String[] args) {
        int[] push = { 1, 2, 3, 4, 5 };
        int[] pop1 = { 4, 5, 3, 2, 1 };
        int[] pop2 = { 4, 3, 5, 1, 2 };

        System.out.println(isPopOrder(push, pop1));// true
        System.out.println(isPopOrder(push, pop2));// false
    }
}

輸出:

true
false

參考文章
圖解
【劍指Offer學習】【面試題22:棧的壓入、彈出序列】

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容