LeetCode:301 删除无效的括号 BFS

题目描述

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

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

示例 1:
输入: "()())()"
输出: ["()()()", "(())()"]

示例 2:
输入: "(a)())()"
输出: ["(a)()()", "(a())()"]

示例 3:
输入: ")("
输出: [""]

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/remove-invalid-parentheses
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路

对每一个位置都有删除和不删除两个选项,可以暴力dfs,但是显然时间复杂度无法接受,是O(2^n)

分析得到最优解的路径,假设需要删除x个括号
第一次删除 某个位置 的括号,可能有多个位置
第二对第一次删除后的结果,再删除某个位置的括号

操作x次后,得到的结果集合就是答案
在这里插入图片描述

这样的操作树,刚好满足BFS的特征

  • 使用哈希set来存储string类,作为每次的起始集合
  • 遍历起始集合的所有string,对每个string,枚举删除的位置
  • 得到下一层的结果集合,令起始集合 = 这个集合
  • 一旦找到合法的括号,那么这一层所有的括号都合法

假设删除x次,那么我们就只用做x次删除,必定找得到答案,大大避免了不必要的搜索(比如删除x+1次以及他们之后的情况),这也是为何bfs在这个问题上优于dfs

而且使用集合的bfs可以有效避免重复的情况

代码

class Solution {
public:
    // 判断合法
    bool isValid(string& s)
    {
        deque<char> q;
        for(int i=0; i<s.length(); i++)
        {
            if(s[i]!='(' && s[i]!=')') continue;
            if(s[i]=='(') q.push_back(s[i]);
            else if(s[i]==')' && !q.empty()) q.pop_back(); 
            else if(s[i]==')' && q.empty()) return false;
        }
        return q.empty();
    }
    vector<string> removeInvalidParentheses(string s)
    {
        if(isValid(s)) return vector<string>{s};
        unordered_set<string> now{s};
        unordered_set<string> ans;
        while(1)
        {
            unordered_set<string> next;
            bool flag = false;
            for(auto it=now.begin(); it!=now.end(); it++)
            {
                // 计算括号个数,如果为0说明访问到叶子节点,需要退出
                int cnt = 0;
                for(int i=0; i<(*it).length(); i++)
                    if((*it)[i]=='(' || (*it)[i]==')') cnt++;
                if(cnt==0) {flag=true; break;}
                // 枚举当前层每个节点不同位置,删除一个括号
                for(int i=0; i<(*it).length(); i++)
                {
                    string str = *it;
                    if(str[i]!='(' && str[i]!=')') continue;
                    str.erase(str.begin()+i);
                    next.insert(str);
                    if(isValid(str)) {flag=true; ans.insert(str);}
                }
            }
            if(flag) break;
            now = next;
        }
        return vector<string>(ans.begin(), ans.end());
    }
};
发布了199 篇原创文章 · 获赞 7 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_44176696/article/details/104691942