leetcode 301. 删除无效的括号

删除最小数量的无效括号,使得输入的字符串有效,返回所有可能的结果。
说明: 输入可能包含了除 ( 和 ) 以外的字符。
示例 1:
输入: “()())()”
输出: [“()()()”, “(())()”]
示例 2:
输入: “(a)())()”
输出: [“(a)()()”, “(a())()”]
示例 3:
输入: “)(”
输出: [“”]

思路:做过括号匹配都知道:用一个栈来模拟匹配过程,'('入栈,')'出栈,若栈为空说明该串是符合题意的。
现在我们需要做的就是对括号进行删除,我们遍历从前往后遍历可以删除不符合的')'括号,从后往前遍历可以删除
不符合的'('括号,我们利用bfs,不断对队列的字符串进行checkLeft和checkRight,若遇到ture,说明
当前的字符串已经是删除最少无效的括号的最优解了,接着就对队列中的其他字符串进行check即可,符合加入List中。
public class Solution {
    public List<String> removeInvalidParentheses(String s) {
        queue.offer(s);
        vis.add(s);
        boolean flag=false;
        List<String> ans=new ArrayList<String>();
        while (!queue.isEmpty()){
            String cur=queue.poll();
            if(flag){
                check(cur,ans);
            }else{
                flag=checkLeft(cur,ans)||checkRight(cur,ans);
            }
        }
        if(ans.size()==0){
            ans.add("");
        }
        return new ArrayList<String>(ans);
    }

    Set<String> vis=new HashSet<String>();
    Queue<String> queue=new LinkedList<String>();

    public void check(String s,List<String> ans){  //查看是否正确
        Stack<Character> st=new Stack<Character>();
        for(char c:s.toCharArray()){
            if(c=='('){
                st.push(c);
            }
            if(c==')'){
                if(st.isEmpty()){
                    return;
                }
                st.pop();
            }
        }
        if(st.isEmpty()){
            ans.add(s);
        }
    }

    public boolean checkLeft(String s,List<String> ans){ //检查左边
        //delete right
        Stack<Character> st=new Stack<Character>();
        for(int i=0;i<s.length();++i){
            if(s.charAt(i)=='('){
                st.push(s.charAt(i));
            }else if(s.charAt(i)==')'){
                if(st.isEmpty()){
                    for(int j=i;j>=0;--j){ //删除不符合的')'  多种情况
                        if(s.charAt(j)==')'){
                            String s1=s.substring(0,j)+s.substring(j+1);
                            if(!vis.contains(s1)){
                                vis.add(s1);
                                queue.offer(s1);
                            }
                        }
                    }
                    return false;
                }else{
                    st.pop();
                }
            }
        }
        if(st.isEmpty()){
            ans.add(s);
            return true;
        }
        return false;
    }

    public boolean checkRight(String s,List<String> ans){ //检查右边
        //delete right
        Stack<Character> st=new Stack<Character>();
        st.clear();
        for(int i=s.length()-1;i>=0;--i){
            if(s.charAt(i)==')'){
                st.push(s.charAt(i));
            }else if(s.charAt(i)=='('){
                if(st.isEmpty()){
                    for(int j=i;j<s.length();++j){
                        if(s.charAt(j)=='('){  //删除不符合的'(' 多种情况
                            String s1=s.substring(0,j)+s.substring(j+1);
                            if(!vis.contains(s1)){
                                vis.add(s1);
                                queue.add(s1);
                            }
                        }
                    }
                    return false;
                }else{
                    st.pop();
                }
            }
        }
        if(st.isEmpty()){
            ans.add(s);
            return true;
        }
        return false;
    }
}
//上面的代码直接改成dfs也可以。
Set<String> vis=new HashSet<String>();
    char[] c={'(',')'};

    public List<String> removeInvalidParentheses(String s) {
        vis.add(s);
        List<String> ans=new ArrayList<String>();
        checkLeft(s,ans);
        return new ArrayList<String>(ans);
    }

    public void checkLeft(String s,List<String> ans){
        //delete right
        Stack<Character> st=new Stack<Character>();
        for(int i=0;i<s.length();++i){
            if(s.charAt(i)==c[0]){
                st.push(s.charAt(i));
            }else if(s.charAt(i)==c[1]){
                if(st.isEmpty()){
                    for(int j=i;j>=0;--j){
                        if(s.charAt(j)==c[1]){
                            String s1=s.substring(0,j)+s.substring(j+1);
                            if(!vis.contains(s1)){
                                vis.add(s1);
                                checkLeft(s1,ans);
                            }
                        }
                    }
                    return;
                }else{
                    st.pop();
                }
            }
        }
        if(st.isEmpty()){
            ans.add(s);
        }
        checkRight(s,ans);
    }

    public void checkRight(String s,List<String> ans){
        //delete right
        Stack<Character> st=new Stack<Character>();
        st.clear();
        for(int i=s.length()-1;i>=0;--i){
            if(s.charAt(i)==c[1]){
                st.push(s.charAt(i));
            }else if(s.charAt(i)==c[0]){
                if(st.isEmpty()){
                    for(int j=i;j<s.length();++j){
                        if(s.charAt(j)==c[0]){
                            String s1=s.substring(0,j)+s.substring(j+1);
                            if(!vis.contains(s1)){
                                vis.add(s1);
                                checkRight(s1,ans);
                            }
                        }
                    }
                    return;
                }else{
                    st.pop();
                }
            }
        }
        if(st.isEmpty()){
            if(!ans.contains(s)){
                ans.add(s);
            }
        }
    }
//dfs二:
public class Solution {
    public List<String> removeInvalidParentheses(String s) {
        int leftCnt=0;
        int rightCnt=0;
        //删除多余的左右括号
        for(char cur:s.toCharArray()){
            if(cur==c[0]){
                ++leftCnt;
            }
            if(cur==c[1]){
                if(leftCnt>0){
                    --leftCnt;
                }else{
                    ++rightCnt;
                }
            }
        }
        Set<String> vis=new HashSet<String>();
        List<String> ans=new ArrayList<String>();
        vis.add(s);
        delete(0,s,leftCnt,rightCnt,ans,vis);
        Collections.reverse(ans); //将结果进行翻转 
        return ans;
    }
    public void delete(int idx,String s,int leftCnt,int rightCnt,List<String> ans,Set<String> vis){
        if(leftCnt==0&&rightCnt==0){
            if(check(s)){
                ans.add(s);
            }
            return;
        }
        for(int i=idx;i<s.length();++i){
            if(i!=idx&&s.charAt(i)==s.charAt(i-1)){ //重复括号不需要删除 该状态之前已经有了
                continue;
            }
            if(leftCnt>0&&s.charAt(i)==c[0]){ //删除多余左括号
                String s1=s.substring(0,i)+s.substring(i+1);
                if(!vis.contains(s1)){
                    delete(i,s1,leftCnt-1,rightCnt,ans,vis);
                }
            }
            if(rightCnt>0&&s.charAt(i)==c[1]){ //删除多余右括号
                String s1=s.substring(0,i)+s.substring(i+1);
                if(!vis.contains(s1)){
                    delete(i,s1,leftCnt,rightCnt-1,ans,vis);
                }
            }
        }
    }

    public char[] c={'(',')'};
    public boolean check(String s){
        int match=0; //利用match模拟栈
        for(char cur:s.toCharArray()){
            if(cur==c[0]){
                ++match;
            }else if(cur==c[1]){
                --match;
            }
            if(match<0){
                return false;
            }
        }
        return match==0;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值