leetcode22 括号生成

思路:

1.(吐槽)这一题让你生成有效括号,又不告诉你什么是有效括号。那你让我做什么?

那么到底什么是快乐星球(不对,有效括号)?

这个问题的答案,其实就是这题的灵魂了:'('一定要有闭环才行。

=============version 1  只打败了10%的人===========

我一开始也没想很清楚,想着先把所有括号生成出来再说。那么经典的暴力搜索开始:

可以看到我是在最后生成了所有的字串后,再去字串判断是否符合题意(if(deep==2*n){...}的代码块内)。

if(rightCount>leftCount) 这一句其实最开始没想到的,如果我一开始就有这个逻辑,那么代码当然可以优化。即这一题的第二个考点:剪枝。

class Solution {
    public List<String> generateParenthesis(int n) {
        if(n == 0) {
            return new ArrayList<String>();
        }
        StringBuilder sb = new StringBuilder();
        List<String> resList = new ArrayList<>();
        dfs(0,sb,n,resList);
        return resList;
    }

    void dfs(int deep,StringBuilder sb,int n,List<String> resList) {
        if(deep == 2*n) {
            //比对答案了
            int leftCount = 0;
            int rightCount = 0;
            for(int i=0,len = sb.length();i<len;i++) {
                if(sb.charAt(i) == '(') 
                    leftCount++;
                else 
                    rightCount++;

                // 这个是调试过程中得出的结论
                if(rightCount>leftCount) {
                    break;
                }
                // 正确答案
                if(i == len-1 && leftCount == rightCount) {
                    resList.add(sb.toString());
                }
            }
            return;
        }
        
        sb.append('(');
        dfs(deep+1,sb,n,resList);
        // 开头就剪枝收益很大
        if(deep != 0) {
            sb.deleteCharAt(sb.length()-1);
            sb.append(')');
            dfs(deep+1,sb,n,resList);
            sb.deleteCharAt(sb.length()-1);
        }
        
    }
}

=============version 2 打败了97%的人===========

有了刚才的经验,我们知道,在dfs搜索的过程中,其实是可以提前剪枝的。

当我们发现sb中 ')' 的数目大于 '(' 的数目,就可以不用往下进行dfs搜索了。

代码如下(我在dfs函数中加了两个参数:leftCount和rightCount):

class Solution {
    public List<String> generateParenthesis(int n) {
        if(n == 0) {
            return new ArrayList<String>();
        }
        StringBuilder sb = new StringBuilder();
        List<String> resList = new ArrayList<>();
        dfs(0,sb,n,resList,0,0);
        return resList;
    }

    void dfs(int deep,StringBuilder sb,int n,List<String> resList,int leftCount,int rightCount) {
        if(deep == 2*n) {
            // 正确答案
            if(leftCount == rightCount) {
                resList.add(sb.toString());
            }
            return;   
        }
        if(rightCount > leftCount){
            return;
        }
              
        sb.append('(');
        dfs(deep+1,sb,n,resList,leftCount+1,rightCount);
        sb.deleteCharAt(sb.length()-1);

        sb.append(')');
        dfs(deep+1,sb,n,resList,leftCount,rightCount+1);
        sb.deleteCharAt(sb.length()-1);
        
        return; 
    }
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值