力扣301题,删除无效的括号

力扣301题,删除无效的括号

题目描述

给你一个由若干括号和字母组成的字符串 s ,删除最小数量的无效括号,使得输入的字符串有效。

返回所有可能的结果。答案可以按 任意顺序 返回。

输入输出样例

输入:s = "()())()"
输出:["(())()","()()()"]
输入:s = "(a)())()"
输出:["(a())()","(a)()()"]
输入:s = ")("
输出:[""]

解法一:使用DFS+剪枝

class Solution
{
public:
//删除最小数量的括号,使得输入的字符串有效
    vector<string>removeInvalidParenthese(string s)
    {
        //定义最小需要去除的左括号的数目与右括号的数目
        int lRemove=0;
        int rRemove=0;

        for(char c:s)
        {
            if(c=='(')
            {
                lRemove++;
            }
            else if(c==')')
            {
                //确保在左右括号有效的前提下更新最小需要去除的左右括号的数目
                if(lRemove==0)
                {
                    rRemove++;
                }
                else{
                    lRemove--;
                }
            }
        }

        vector<string>res;
        //去除字符串中无效的括号
        removeParentheses(s,res,0,lRemove,rRemove);
        return res;
    }

    void removeParentheses(string str,vector<string>&res,int start,int lRemove,int rRemove)
    {
        //需要更新的最小括号数目均为0时,那么则判断该字符串是否是有效的括号
        if(lRemove==0&&rRemove==0)
        {
            if(isValid(str))
            {
                res.push_back(str);
            }
            return;
        }

        for(int i=start;i<str.size();i++)
        {
            //跳过之前相同的元素值,相当于剪枝
            if(i!=start&&str[i]==str[i-1])
            {
                continue;
            }
            //如果剩余的字符无法满足去掉的数量需求,直接返回
            if(lRemove+rRemove>str.size()-i)
            {
                return;
            }

            //尝试去掉一个左括号
            if(lRemove>0&&str[i]=='(')
            {
                string tempStr=str.substr(0,i)+str.substr(i+1);
                removeParentheses(tempStr,res,i,lRemove-1,rRemove);
            }

            //尝试去掉一个右括号
            if(rRemove>0&&str[i]==')')
            {
                string tempStr=str.substr(0,i)+str.substr(i+1);
                removeParentheses(tempStr,res,i,lRemove,rRemove-1);
            }
        }

    }

    //判断是否为有效的括号
    bool isValid(string s)
    {
        stack<char>stk;

        for(auto i:s)
        {
            if(!stk.empty())
            {
                char temp=stk.top();
                if(temp=='('&&i==')')
                {
                    stk.pop();
                    continue;
                }
            }
            if(i=='(')
            {
                stk.push(i);
            }
        }
        return stk.empty();
    }
};

解法二:BFS

//使用广度优先
class bfsSolution
{
public:
    //判断是否为有效的括号
    bool isValid(string s)
    {
        stack<char>stk;

        for(auto i:s)
        {
            if(!stk.empty())
            {
                char temp=stk.top();
                if(temp=='('&&i==')')
                {
                    stk.pop();
                    continue;
                }
            }
            if(i=='('||i==')')
            {
                stk.push(i);
            }
        }
        return stk.empty();
    }

//使用广度优先搜索的方法实现去除多余的括号
    vector<string>removeInvalidParenthese(string str)
    {
        vector<string>res;
        unordered_set<string>currStr;
        
        //往hash表中插入原始字符串
        currStr.insert(str);

        //进行层序遍历
        while(true)
        {
            //将括号字符串先按照从1到字符串长度递减操作
            //直至出现能满足有效字符串的值
            //只要大于一便可以弄进结果中
            for(auto &str:currStr)
            {
                if(isValid(str))
                {
                    res.push_back(str);
                }
            }

            if(res.size()>0)
            {
                return res;
            }

            //保存切分的数组
            unordered_set<string>nextStr;

            for(auto &str:currStr)
            {
                for(int i=0;i<str.size();i++)
                {
                    //跳过前一个值和后一个值相同的情况,因为此时无论删除那个都不影响
                    if(i>0&&str[i]==str[i-1])
                    {
                        continue;
                    }
                    //切分字符串
                    if(str[i]=='('||str[i]==')')
                    {
                        string tempStr=str.substr(0,i)+str.substr(i+1);
                        nextStr.insert(tempStr);
                    }
                }

            }
            currStr=nextStr;
            

        }
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值