讀完本文,你能夠去力扣拿下以下題目:git
20.有效的括號github
-----------算法
對括號的合法性判斷是一個很常見且實用的問題,好比說咱們寫的代碼,編輯器和編譯器都會檢查括號是否正確閉合。並且咱們的代碼可能會包含三種括號 [](){}
,判斷起來有一點難度。數據結構
本文就來聊一道關於括號合法性判斷的算法題,相信能加深你對棧這種數據結構的理解。編輯器
題目很簡單,輸入一個字符串,其中包含 [](){}
六種括號,請你判斷這個字符串組成的括號是否合法。code
Input: "()[]{}" Output: true Input: "([)]" Output: false Input: "{[]}" Output: true
解決這個問題以前,咱們先下降難度,思考一下,若是隻有一種括號 ()
,應該如何判斷字符串組成的括號是否合法呢?leetcode
PS:我認真寫了 100 多篇原創,手把手刷 200 道力扣題目,所有發佈在 labuladong的算法小抄,持續更新。建議收藏,按照個人文章順序刷題,掌握各類算法套路後投再入題海就如魚得水了。字符串
字符串中只有圓括號,若是想讓括號字符串合法,那麼必須作到:get
每一個右括號 )
的左邊必須有一個左括號 (
和它匹配。編譯器
好比說字符串 ()))((
中,中間的兩個右括號左邊就沒有左括號匹配,因此這個括號組合是不合法的。
那麼根據這個思路,咱們能夠寫出算法:
bool isValid(string str) { // 待匹配的左括號數量 int left = 0; for (char c : str) { if (c == '(') left++; else // 遇到右括號 left--; if (left < 0) return false; } return left == 0; }
若是隻有圓括號,這樣就能正確判斷合法性。對於三種括號的狀況,我一開始想模仿這個思路,定義三個變量 left1
,left2
,left3
分別處理每種括號,雖然要多寫很多 if else 分支,可是彷佛能夠解決問題。
但實際上直接照搬這種思路是不行的,好比說只有一個括號的狀況下 (())
是合法的,可是多種括號的狀況下, [(])
顯然是不合法的。
僅僅記錄每種左括號出現的次數已經不能作出正確判斷了,咱們要加大存儲的信息量,能夠利用棧來模仿相似的思路。
棧是一種先進後出的數據結構,處理括號問題的時候尤爲有用。
咱們這道題就用一個名爲 left
的棧代替以前思路中的 left
變量,遇到左括號就入棧,遇到右括號就去棧中尋找最近的左括號,看是否匹配。
bool isValid(string str) { stack<char> left; for (char c : str) { if (c == '(' || c == '{' || c == '[') left.push(c); else // 字符 c 是右括號 if (!left.empty() && leftOf(c) == left.top()) left.pop(); else // 和最近的左括號不匹配 return false; } // 是否全部的左括號都被匹配了 return left.empty(); } char leftOf(char c) { if (c == '}') return '{'; if (c == ')') return '('; return '['; }
_____________
個人 在線電子書 有 100 篇原創文章,手把手帶刷 200 道力扣題目,建議收藏!對應的 GitHub 算法倉庫 已經得到了 70k star,歡迎標星!