幾道和「堆棧、隊列」有關的面試算法題

題目一:有效的括號

問題描述

給定一個只包括 '(',')','{','}','[',']' 的字符串,判斷字符串是否有效。java

解題思路

這道題讓咱們驗證輸入的字符串是否爲括號字符串,包括大括號,中括號和小括號。node

這裏咱們使用小程序

  • 遍歷輸入字符串
  • 若是當前字符爲左半邊括號時,則將其壓入棧中
  • 若是遇到右半邊括號時,分類討論:
  • 1)如棧不爲空且爲對應的左半邊括號,則取出棧頂元素,繼續循環
  • 2)若此時棧爲空,則直接返回 false
  • 3)若不爲對應的左半邊括號,反之返回 false

動畫演示

20. Valid Parentheses

代碼實現

class Solution {
    public boolean isValid(String s) {
        Stack<Character> stack = new Stack<>();
        char[] chars = s.toCharArray();
        for (char aChar : chars) {
            if (stack.size() == 0) {
                stack.push(aChar);
            } else if (isSym(stack.peek(), aChar)) {
                stack.pop();
            } else {
                stack.push(aChar);
            }
        }
        return stack.size() == 0;
    }
    
    private boolean isSym(char c1, char c2) {
        return (c1 == '(' && c2 == ')') || (c1 == '[' && c2 == ']') || (c1 == '{' && c2 == '}');
    }
}
複製代碼

題目二:用兩個棧實現隊列

問題描述

用兩個棧來實現一個隊列,完成隊列的 Push 和 Pop 操做。數據結構

解題思路

in 棧用來處理入棧(push)操做,out 棧用來處理出棧(pop)操做。一個元素進入 in 棧以後,出棧的順序被反轉。當元素要出棧時,須要先進入 out 棧,此時元素出棧順序再一次被反轉,所以出棧順序就和最開始入棧順序是相同的,先進入的元素先退出,這就是隊列的順序。函數

  • push 元素時,始終是進入棧,pop 和 peek 元素時始終是走出棧。
  • pop 和 peek 操做,若是出棧爲空,則須要從入棧將全部元素移到出棧,也就是調換順序,好比開始push的順序是 3-2-1,1 是最早進入的元素,則到出棧的順序是 1-2-3,那 pop 操做拿到的就是 1,知足了先進先出的特色。
  • pop 和 peek 操做,若是出棧不爲空,則不須要從入棧中移到數據到出棧。

動畫 1

代碼實現

Stack<Integer> in = new Stack<Integer>();
Stack<Integer> out = new Stack<Integer>();

public void push(int node) {
    in.push(node);
}

public int pop() throws Exception {
    if (out.isEmpty())
        while (!in.isEmpty())
            out.push(in.pop());

    if (out.isEmpty())
        throw new Exception("queue is empty");

    return out.pop();
}
複製代碼

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

問題描述

輸入兩個整數序列,第一個序列表示棧的壓入順序,請判斷第二個序列是否爲該棧的彈出順序。假設壓入棧的全部數字均不相等。例如序列 1,2,3,4,5 是某棧的壓入順序,序列 4,5,3,2,1是該壓棧序列對應的一個彈出序列,但4,3,5,1,2就不多是該壓棧序列的彈出序列。(注意:這兩個序列的長度是相等的)動畫

解題思路

借用一個輔助的棧,遍歷壓棧順序,先講第一個放入棧中,這裏是 1,而後判斷棧頂元素是否是出棧順序的第一個元素,這裏是 4,很顯然 1≠4 ,因此須要繼續壓棧,直到相等之後開始出棧。spa

出棧一個元素,則將出棧順序向後移動一位,直到不相等,這樣循環等壓棧順序遍歷完成,若是輔助棧還不爲空,說明彈出序列不是該棧的彈出順序。3d

代碼實現

public boolean IsPopOrder(int[] pushSequence, int[] popSequence) {
    int n = pushSequence.length;
    Stack<Integer> stack = new Stack<>();
    for (int pushIndex = 0, popIndex = 0; pushIndex < n; pushIndex++) {
        stack.push(pushSequence[pushIndex]);
        while (popIndex < n && !stack.isEmpty() 
                && stack.peek() == popSequence[popIndex]) {
            stack.pop();
            popIndex++;
        }
    }
    return stack.isEmpty();
}
複製代碼

題目四:包含 min 函數的棧

問題描述

定義棧的數據結構,請在該類型中實現一個可以獲得棧最小元素的 min 函數。code

解題思路

使用兩個 stack,一個做爲數據棧,另外一個做爲輔助棧。其中 數據棧 用於存儲全部數據,而 輔助棧 用於存儲最小值。cdn

舉個🌰:

  1. 入棧的時候:首先往空的數據棧裏壓入數字 3 ,此時 3 是最小值,因此把最小值壓入輔助棧。接下來往數據棧裏壓入數字 4 。因爲 4 大於以前的最小值,所以只要入數據棧,不須要壓入輔助棧。

  2. 出棧的時候:當數據棧和輔助棧的棧頂元素相同的時候,輔助棧的棧頂元素出棧。不然,數據棧的棧頂元素出棧。

  3. 得到棧頂元素的時候:直接返回數據棧的棧頂元素。

  4. 棧最小元素:直接返回輔助棧的棧頂元素。

代碼實現

private Stack<Integer> dataStack = new Stack<>();
private Stack<Integer> minStack = new Stack<>();

public void push(int node) {
    dataStack.push(node);
    minStack.push(minStack.isEmpty() ? node : Math.min(minStack.peek(), node));
}

public void pop() {
    dataStack.pop();
    minStack.pop();
}

public int top() {
    return dataStack.peek();
}

public int min() {
    return minStack.peek();
}
複製代碼

小程序

小程序名稱:圖解劍指offer

劍指offer上面的 66 道題目都挪上去了,每一道題目基本上都有詳細說明解法,更多的解法我還在添加中,須要準備刷題的能夠在坐地鐵的零碎時間拿出來看看^_^

圖 1

圖 2

圖 3

小程序
相關文章
相關標籤/搜索