301. 删除无效的括号--Leecode刷题

本文探讨了一类求解子集并满足特定条件的问题,通过深度优先搜索(DFS)解决去除无效括号的挑战。文章详细分析了如何统计多余括号、执行DFS遍历及检查字符串合法性,提供了完整代码实现。

刷了一个困难题,一如既往做不出来,然后看题解,然后再自己打一遍…记录这个题的原因是,这其实是一类题目!!!先看看题目再分析。

题目描述:

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

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

示例 1:

输入: “()())()”
输出: ["()()()", “(())()”]

示例 2:

输入: “(a)())()”
输出: ["(a)()()", “(a())()”]

示例 3:

输入: “)(”
输出: [""]

分析题目:

这真的是一类题,题目具有的特征:
1.求的是一个子集
2.且子集满足一定的条件

这类题目可以用一个方法,就是DFS

关于这题DFS的分析:

1.DFS遍历的行为?删括号
2.什么情况下删?就是当左括号或者右括号有多的时候,正好当前遍历的又是个多的括号,就删!!!之后再继续进行DFS遍历删除
3.出口是什么?当没有多余的括号的时候!!!但注意此时还需要检查一下当前的字符串是否合法(即左右括号是否匹配!)

解题步骤:

1. 先统计多余的括号,注意并不是循环一遍统计左右括号个数,然后多的一方就是多余的。
如 left= 2,right = 3,就认为右括号多一个,因为可能之前的不匹配!!!
正确的统计方法是,当遇到左括号left++,遇到右括号时,若left > 0 就left --,说明一对括号匹配消除,若left == 0 ,right++,那么这样留下来的就是多余的括号,没有被匹配的括号!!!

2. 然后开始DFS,从第一个字符串开始,若当前符号是多余需要删除,则删除,
如:此时DFS遍历时left = 0,right = 1,当前是s[ i ] 为左括号则跳过,若为右括号则删除,
然后对后面进行递归DFS。
3. 直到left 为 0 ,right为 0,进行检查,匹配加入set< string >

代码如下:
class Solution {
public:
    bool checks(string s){
        int left = 0;
        for(int i = 0;i < s.size();i++){
            if(s[i] == '(') left++;
            else if(s[i] == ')'){
                if(!left) return false;
                else left--;
            }
        }

        return true;
    }

    void dfs(set<string> &result,string s,int left,int right,int index){
        if(!left&&!right){
            if(checks(s)) result.insert(s);
            return ;
        }

        for(int i = index;i < s.size();i++){
            if(s[i] == '('&&left) dfs(result,s.substr(0,i)+s.substr(i+1,s.size()-i-1),left-1,right,i);
            else if(s[i] == ')'&&right) dfs(result,s.substr(0,i)+s.substr(i+1,s.size()-i-1),left,right-1,i);
        }

    }

    vector<string> removeInvalidParentheses(string s) {

       int left = 0;
       int right = 0;

       for(int i = 0;i < s.size();i++){
           if(s[i] == '(') left++;
           else if(s[i] == ')'){
               if(left > 0) left--;
               else right++;
           }
       }

        set<string> result;
        dfs(result,s,left,right,0);

        return vector<string>(result.begin(),result.end());

    }
};

总结:
关于DFS不要怕,步骤就是,首先递归的操作,其次递归的出口!!!

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值