LeetCode-301. 删除无效的括号 ——广度优先搜索(BFS)

在这里插入图片描述
为何用BFS而不是DFS
利用BFS理解起来要远远比DFS要简单的多,因为这道题说的是删除最少的括号!!,如果我们每次只删除一个括号,然后观察被删除一个括号后是否合法,如果已经合法了,我们就不用继续删除了啊。因此我们并不需要将遍历进行到底,而是层层深入,一旦达到需求,就不再深入了。

如何进行BFS
在进行BFS之前,要先判断 ’ ( '和 ’ ) '是否有需要删除的,然后在根据需要删除的 ’ ( '和 ’ ) '的数量,他们对应的需要删除的数量对应的就是需要进行搜索的层数。
(即假如需要删除的 '(‘的数量是2,那么第一次先列举出删除一个’('后的所有可能的情况(不管删除以后是否合法),然后在在这基础上重复之前的操作再列举再删除一个’('后的所有情况)
以题目的例子为例
在这里插入图片描述
通过判断知道需要删除的只有一个 ‘)’(因为’(‘有3个,而’)‘有4个,显然’)‘多了一个)
那么就列举出在删除一个’ ) '后的所有可能的情况
第一层:[ ( ( ) ) ( ) , ( ) ( ) ( ) , ( ) ( ) ( ) , ( ) ( ) ) ( ]
由于只需删除一个,所有列举一次就行,然后只需对该层的所有结果进行合法性判断
注(由于可能在列举过程中会出现重复的现象,因此可以使用set来进行每一层数据的存储,避免重复)

代码如下

class Solution {
    public List<String> removeInvalidParentheses(String s) {
        //统计需要删除的'('和')'的数量
        int left=0;
        int right=0;
        for (int i=0;i<s.length();i++){
            if (s.charAt(i)=='('){
                left ++;
            }else if (s.charAt(i)==')'){
                if (left>0){
                    left--;
                }else {
                    right++;
                }
            }
        }
        ArrayList<String> arry = new ArrayList<String>();
        HashSet<String> set = new HashSet<String>();
        ArrayList<String> output = new ArrayList<String>();
        arry.add(s);
    
        //删除'('
        while (left>0){
            ArrayList<String> temp = new ArrayList<String>();
            for (int i=0;i<arry.size();i++){
                String str = arry.get(i);
                for (int j=0;j<str.length();j++){
                    if (str.charAt(j)=='('){
                        String remove = str.substring(0,j)+str.substring(j+1);
                        if (!set.contains(remove)){
                            set.add(remove);
                            temp.add(remove);
                        }
                    }
                }
            }
            arry = temp;
            left--;
        }
        //删除')'
        while (right>0){
            ArrayList<String> temp = new ArrayList<String>();
            for (int i=0;i<arry.size();i++){
                String str = arry.get(i);
                for (int j=0;j<str.length();j++){
                    if (str.charAt(j)==')'){
                        String remove = str.substring(0,j)+str.substring(j+1);
                        if (!set.contains(remove)){
                            set.add(remove);
                            temp.add(remove);
                        }
                    }
                }
            }
            arry = temp;
            right--;
        }
        //将删除后的所有字符串进行合法性判断,如果合法则加入list集合中
        for (String word:arry){
             if (judge(word)){
                 output.add(word);
             }
        }
        return output;

    }

    private boolean judge(String word) {
        Stack<Character> stack = new Stack<Character>();
        for (int i=0;i<word.length();i++){
            char c = word.charAt(i);
            if (c=='('){
                stack.add(c);
            }else if (c==')'){
                if (stack.size()>0){
                    stack.pop();
                }else {
                    return false;
                }
            }
        }
        return true;
    }
}

在这里插入图片描述

总结:用该方法很明了地体现了广度优先搜索的分层(层层递进)进行搜索的特点

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值