LeetCode(3) 有效的括號
阿新 • • 發佈:2018-11-27
給定一個只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字串,判斷字串是否有效。
有效字串需滿足:
左括號必須用相同型別的右括號閉合。
左括號必須以正確的順序閉合。
注意空字串可被認為是有效字串。
示例 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