LeetCode 678. 有效的括号字符串--DFS+剪枝

  1. 有效的括号字符串
    给定一个只包含三种字符的字符串:( ,) 和 *,写一个函数来检验这个字符串是否为有效字符串。有效字符串具有如下规则:

任何左括号 ( 必须有相应的右括号 )。
任何右括号 ) 必须有相应的左括号 ( 。
左括号 ( 必须在对应的右括号之前 )。

  • 可以被视为单个右括号 ) ,或单个左括号 ( ,或一个空字符串。
    一个空字符串也被视为有效字符串。
    示例 1:

输入: “()”
输出: True
示例 2:

输入: “(*)”
输出: True
示例 3:

输入: “(*))”
输出: True
注意:

字符串大小将在 [1,100] 范围内。

题解:
因为字符串长度最多为100,所以可以想到是DFS方面,就直接DFS判断,然后减枝避免超时,如何减枝呢?主要是针对’*‘应该改为’(‘还是’)‘还是空,根据括号匹配原则,我们知道如果从左到右依次遍历,出现到左括号数目为sum1,右括号数目为sum2,如果sum2>sum1就直接错误,这个不难理解,然后假设ans1为整个字符串’(‘的数目,ans2为整个字符串’)‘的数目,ans3为整个字符串’*‘的数目,那么有如下关系:
如果’*‘改为’(’,则ans1++,ans3- -;
如果’*‘改为‘)’,则ans2++,ans3- -;
如果’*‘改为空,则ans3- -;
于是判断如果abs(ans1-ans2)>ans3说明错误,为何呢?因为’*'可以看成是调节左右括号数目的存在,如果左右括号数目差异已经大于能够调节的范围,就肯定错误。

AC代码

class Solution {
public:
    bool check(string s)
    {
        int ans=0;
        for(int i=0;i<s.length();i++)
        {
            if(s[i]=='?')continue;
            if(s[i]=='(')ans++;
            else if(s[i]==')')
            {
                if(ans==0)return false;
                ans--;
            }
        }
        if(ans>0)return false;
        return true;
    }
    string s;
    bool dfs(int pos,int ans1,int ans2,int ans3,int sum1,int sum2)
    {
        if(pos==s.length())
        {   
            if(check(s))
            {
                return true;
            }
            return false;
        }
        if(sum1<sum2)return false;
        if(abs(ans1-ans2)>ans3)return false;
        bool res=false;
        if(s[pos]=='(')
            res=dfs(pos+1,ans1,ans2,ans3,sum1+1,sum2);
        else if(s[pos]==')')
            res=dfs(pos+1,ans1,ans2,ans3,sum1,sum2+1);
        else if(s[pos]=='*')
        {
            s[pos]='(';
            res=dfs(pos+1,ans1+1,ans2,ans3-1,sum1+1,sum2);
            if(res)return true;
            s[pos]=')';
            res=dfs(pos+1,ans1,ans2+1,ans3-1,sum1,sum2+1);
            if(res)return true;
            s[pos]='?';
            res=dfs(pos+1,ans1,ans2,ans3-1,sum1,sum2);
            if(res)return true;
            s[pos]='*';
            return false;
        }
        return res;
    }
    bool checkValidString(string t) {
        s=t;
        int ans1=0,ans2=0,ans3=0;
        for(int i=0;i<s.length();i++)
        if(s[i]=='(')ans1++;
        else if(s[i]==')')ans2++;
        else if(s[i]=='*')ans3++;
        return dfs(0,ans1,ans2,ans3,0,0);
    }
};

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值