【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 个字符。

posted @ 2020-09-12 11:18  Flix  阅读(360)  评论(0编辑  收藏  举报