1. 程式人生 > >LeetCode(3) 有效的括號

LeetCode(3) 有效的括號

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

有效字串需滿足:

左括號必須用相同型別的右括號閉合。
左括號必須以正確的順序閉合。
注意空字串可被認為是有效字串。

示例 1:

輸入: “()”
輸出: true

示例 2:

輸入: “()[]{}”
輸出: true

示例 3:

輸入: “(]”
輸出: false

示例 4:

輸入: “([)]”
輸出: false

示例 5:

輸入: “{[]}”
輸出: true

思路:

1. 初始化棧 S。
2. 一次處理表達式的每個括號。
3. 如果遇到開括號,我們只需將其推到棧上即可。這意味著我們將稍後處理它,讓我們簡單地轉到前面的 子表示式。
4. 如果我們遇到一個閉括號,那麼我們檢查棧頂的元素。如果棧頂的元素是一個 相同型別的左括號,那麼我們將它從棧中彈出並繼續處理。否則,這意味著表示式無效。
5. 如果到最後我們剩下的棧中仍然有元素,那麼這意味著表示式無效。

官方解答:

 class Solution {

        // 處理對映的雜湊表
        private HashMap<Character, Character> mappings;

        // 用對映初始化雜湊對映,使程式碼更易讀
        public  Solution() {
            this.mappings = new HashMap<Character, Character>();
            this.mappings.put(')', '(');
            this.mappings.put('}', '{');
            this.mappings.put(']', '[');
        }


        public  boolean isValid(String s) {

            // 初始化棧
            Stack<Character> stack = new Stack<Character>();

            for (int i = 0; i < s.length(); i++) {
                //索引為i的字串
                char c = s.charAt(i);

                // 如果當前字元是關閉括號
                if (this.mappings.containsKey(c)) {

                    // 獲取堆疊的頂部元素。 如果棧頂是空,則設定#值。如果不為空,移除棧頂
                    char topElement = stack.empty() ? '#' : stack.pop();

                    // 如果此括號的對映與堆疊的頂部元素不匹配,返回false
                    if (topElement != this.mappings.get(c)) {
                        return false;
                    }
                } else {
                    // 如果當前字元是開啟的括號,則入棧
                    stack.push(c);
                }
            }

            // 如果堆疊仍然包含元素,則它是無效表示式
            return stack.isEmpty();
        }

    }

官方的解答優雅極了,也很好理解。最關鍵的一步是用對映初始化雜湊對映,這樣反括號對應的正括號,就有了鍵值對的關係。方便了後面反括號的判斷!
但是,這個題括號只有三種類型,在根本是簡化了難度。所以我們有一種更簡潔的思想來解答。

思路如下:

1. 如果是正括號,則入棧對應的反括號;
2. 如果是反括號,如果棧為空並且棧頂不等於對應的反括號,則返回false,此時移除棧頂元素;
3. 直到最後棧為空,則判斷是有效的括號。

public class Solution {

    public static boolean isValid(String s) {
        Stack<Character> stack = new Stack<Character>();
        for (char c : s.toCharArray()) {
            if (c == '(')
                stack.push(')');     //入棧
            else if (c == '{')
                stack.push('}');     //入棧
            else if (c == '[')
                stack.push(']');     //入棧
            else if (stack.isEmpty() || stack.pop() !=c)    //棧是否為空,棧頂是否等於c,判斷之和並移除棧頂元素
                return false;
        }
        return stack.isEmpty();      //最後棧為空,則放回true
    }

    public static void main(String[] args) {
        String str = "[())";
        System.out.println(isValid(str));
    }

}

參考:

https://leetcode.com/problems/valid-parentheses/discuss/?orderBy=recent_activity