跳转至

301.删除无效的括号 (Hard)*

题目描述*

删除最小数量的无效括号,使得输入的字符串有效,返回所有可能的结果。

说明: 输入可能包含了除 ( 和 ) 以外的字符。

示例*

输入: "(a)())()"

输出: ["(a)()()", "(a())()"]

代码*

dfs 或 bfs

dfs,首先要求出不合法的左右括号的个数,一次遍历即可,然后 dfs 寻找结果。

bfs 就比较慢了,不太好优化,一层一层遍历。

还有一种带哥的解法,还没太看明白。。。

class Solution {
private:
    bool isValid(string s) {
        int cnt = 0;
        for(auto c : s) {
            if(c == '(') {
                cnt++;
            }else if(c == ')') {
                cnt--;
                if(cnt < 0) {
                    return false;
                }
            }
        }
        return cnt == 0;
    }

    void dfs(string s, int start, int cntLeft, int cntRight, vector<string>& res) {
        if(cntLeft == 0 && cntRight == 0) {
            if(isValid(s)) {
                res.push_back(s);
            }
            return;
        }
        for(int i = start; i < s.length(); i++) {
            // 去重
            if(i - 1 >= start && s[i] == s[i - 1]) {
                continue;
            }
            if(cntLeft > 0 && s[i] == '(') {
                dfs(s.substr(0, i) + s.substr(i + 1), i, cntLeft - 1, cntRight, res);
            }
            if(cntRight > 0 && s[i] == ')') {
                dfs(s.substr(0, i) + s.substr(i + 1), i, cntLeft, cntRight - 1, res);
            }
        }
    }
public:
    vector<string> removeInvalidParentheses(string s) {
        vector<string> res;
        if(s.length() == 0) {
            res.push_back("");
            return res;
        }
        int cntLeft = 0, cntRight = 0;
        for(auto c : s) {
            if(c == '(') {
                cntLeft++;
            }else if(c == ')') {
                if(cntLeft > 0) {
                    cntLeft--;
                }else {
                    cntRight++;
                }
            }
        }
        dfs(s, 0, cntLeft, cntRight, res);
        return res;
    }
};
class Solution {
private:
    bool isValid(string s) {
        int cnt = 0;
        for(auto c : s) {
            if(c == '(') {
                cnt++;
            }else if(c == ')') {
                cnt--;
                if(cnt < 0) {
                    return false;
                }
            }
        }
        return cnt == 0;
    }
public:
    vector<string> removeInvalidParentheses(string s) {
        vector<string> res;
        queue<string> q;
        q.push(s);
        unordered_set<string> visited;
        visited.insert(s);
        bool ifContinue = true;
        while(!q.empty()) {
            string cur = q.front();
            q.pop();
            if(isValid(cur)) {
                res.push_back(cur);
                ifContinue = false;
            }
            if(!ifContinue) {
                continue;
            }
            for(int i = 0; i < cur.length(); i++) {
                if(cur[i] == '(' || cur[i] == ')') {
                    string tmp = cur.substr(0, i) + cur.substr(i + 1);
                    if(!visited.count(tmp)) {
                        q.push(tmp);
                        visited.insert(tmp);
                    }
                }
            }
        }
        return res;
    }
};
class Solution {
public:
    vector<string> removeInvalidParentheses(string s) {
        vector<string> res;
        remove(move(s), {'(', ')'}, 0, 0, res);
        return res;
    }

    void remove(std::string s, const vector<char>& par, int m, int n, vector<string>& res) {
        int stack = 0, i = m;
        for (int i = m; i < s.length(); ++i) {
            if (s[i] == par[0]) stack++;
            if (s[i] == par[1]) stack--;
            if (stack >= 0) continue;
            // "右"括号多出来了,删除一个右括号
            for (int j = n; j <= i; ++j) {
                if (s[j] == par[1] && (j == n || s[j-1] != par[1])) {
                    auto ss = s.substr(0, j) + s.substr(j + 1);
                    remove(move(ss), par, i, j, res);
                }
            }

            return;
        }

        reverse(s.begin(), s.end());
        if (par[0] == '(') {
            remove(move(s), {par[1], par[0]}, 0, 0, res);
        } else {
            res.push_back(move(s));
        }
    }
};

最后更新: July 23, 2022