如何斷定括號合法性

讀完本文,你能夠去力扣拿下以下題目:git

20.有效的括號github

-----------算法

對括號的合法性判斷是一個很常見且實用的問題,好比說咱們寫的代碼,編輯器和編譯器都會檢查括號是否正確閉合。並且咱們的代碼可能會包含三種括號 [](){},判斷起來有一點難度。數據結構

本文就來聊一道關於括號合法性判斷的算法題,相信能加深你對這種數據結構的理解。編輯器

題目很簡單,輸入一個字符串,其中包含 [](){} 六種括號,請你判斷這個字符串組成的括號是否合法。code

Input: "()[]{}"
Output: true

Input: "([)]"
Output: false

Input: "{[]}"
Output: true

解決這個問題以前,咱們先下降難度,思考一下,若是隻有一種括號 (),應該如何判斷字符串組成的括號是否合法呢?leetcode

PS:我認真寫了 100 多篇原創,手把手刷 200 道力扣題目,所有發佈在 labuladong的算法小抄,持續更新。建議收藏,按照個人文章順序刷題,掌握各類算法套路後投再入題海就如魚得水了。字符串

1、處理一種括號

字符串中只有圓括號,若是想讓括號字符串合法,那麼必須作到: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;
}

若是隻有圓括號,這樣就能正確判斷合法性。對於三種括號的狀況,我一開始想模仿這個思路,定義三個變量 left1left2left3 分別處理每種括號,雖然要多寫很多 if else 分支,可是彷佛能夠解決問題。

但實際上直接照搬這種思路是不行的,好比說只有一個括號的狀況下 (()) 是合法的,可是多種括號的狀況下, [(]) 顯然是不合法的。

僅僅記錄每種左括號出現的次數已經不能作出正確判斷了,咱們要加大存儲的信息量,能夠利用棧來模仿相似的思路。

2、處理多種括號

棧是一種先進後出的數據結構,處理括號問題的時候尤爲有用。

咱們這道題就用一個名爲 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,歡迎標星!

相關文章
相關標籤/搜索