1. 程式人生 > 實用技巧 >【LeetCode-BFS】刪除無效的括號

【LeetCode-BFS】刪除無效的括號

題目描述

刪除最小數量的無效括號,使得輸入的字串有效,返回所有可能的結果。

說明: 輸入可能包含了除 ( 和 ) 以外的字元。

示例:

輸入: "()())()"
輸出: ["()()()", "(())()"]

輸入: "(a)())()"
輸出: ["(a)()()", "(a())()"]

輸入: ")("
輸出: [""]

題目連結: https://leetcode-cn.com/problems/remove-invalid-parentheses/

思路

使用 bfs 來做。一層一層地遍歷,如果當前層有字串有效(括號匹配),則說明我們找到了刪除最小括號的答案,就不需要遍歷下一層了。程式碼如下:

class Solution {
public:
    vector<string> removeInvalidParentheses(string s) {
        if(s.empty()) return {""};
        if(isValid(s)) return {s};

        queue<string> q;
        unordered_set<string> lookup; // 記錄字串是否被訪問過
        vector<string> ans;
        q.push(s);
        lookup.insert(s);
        while(!q.empty()){
            int n = q.size();
            for(int i=0; i<n; i++){
                string cur = q.front(); q.pop();
                for(int i=0; i<cur.size(); i++){
                    string temp = cur;
                    if(temp[i]!='(' && temp[i]!=')') continue;
                    string ss = temp.erase(i, 1);  // 注意 erase 的用法,表示刪除從第 i 位置開始的 1 個字元
                    //cout<<ss<<endl;
                    if(lookup.count(ss)==0 && isValid(ss)) ans.push_back(ss);
                    else if(lookup.count(ss)==0) q.push(ss);
                    lookup.insert(ss);
                }
            }
            if(!ans.empty()) return ans; // 這一層找到答案,無需遍歷下一層
        }
        return ans;
    }

    /*判斷 s 中的括號是否匹配*/
    bool isValid(string s){
        int cnt = 0;
        for(auto c:s){
            if(c=='(') cnt++;
            else if(c==')') cnt--;   // 使用 else if,不是 else,因為 s 中可能有除括號外的其他字元
            if(cnt<0) return false;
        }
        return cnt==0;
    }
};

刪除字串的 erase 函式需要注意,使用方法為 s.erase(pos, cnt),表示從位置 pos 開始(包含 pos)刪除 cnt 個字元。