Leecode22 括号生成

题目:

给出 n 代表生成括号的对数,请你写出一个函数,使其能够生成所有可能的并且有效的括号组合。

例如,给出 n = 3,生成结果为:

[
“((()))”,
“(()())”,
“(())()”,
“()(())”,
“()()()”
]

思路:

  1. 递归:求n可以在n-1的答案前面、后面加上一对括号,或者前面加左括号,后面加右括号,但是得注意重复的情况(当答案是”()()()“等类似的情况时,前面加一对括号和后面加一对括号实际上结果是一样的);

  2. 枚举:n个括号可以看作2n长度的数组,每个元素可以填左括号或者右括号,枚举所有可能的组合,然后筛选出符合条件的排列,有2的2n次方种情况,效率较差;

  3. 枚举基础上改进:n个括号实际上合法的只可能是n个左括号和n个右括号,所以在填元素的时候记录个数,如果超过n,则没必要继续往下填,能剪掉一些不必要的分支提升效率;或者当右括号的数量超过左括号的数量,则没必要继续了;

  4. 3点虽然有改进,但整体思路还是在枚举,然后挑选,如果能按照一定的规则填写,填完之后就是满足要求的,那么效率将会更高,这个规则就是:左括号只要不超过n,随时都能填写,右括号则只要不超过左括号的数量,则就能够填写,这样填写出来的string一定能满足要求;虽然时间复杂度没变,但速度快多了;

代码分析:

  1. 第四种思路代码实现分析:在满足左括号数量不大于n,下一个字符可以是左括号,右括号数量不大于左括号数量的情况下,下一个字符可以是右括号,都满足时,则可以是左括号,也可以是右括号,可以理解为深搜,但树的某些分支是没有的,假定leftCount为已有左括号的数量,rightCount为已有右括号的数量,那么当leftCount < n时需要搜索下一个字符是 “( ” 的分支,当rightCount < leftCount时,需要搜索下一个字符是“ ) ”的分支,如果都满足,则都需要搜索,搜索退出的条件即 左括号,右括号的数量都是n,此时,将结果加入到list即可;按照分析,leftCount和rightCount不可能大于n,但是代码中退出条件还是使用了>= n,以防万一写出bug死循环;另外,涉及到字符串的拼接操作,我使用了StringBuilder,底层为动态数据实现,拼接不会产生过多的中间字符串,虽然写起来不太优雅,但效率和空间占用上比直接传递字符串会更好,这题因为一开始就直到有2n个字符,所以直接用数组来实现效率会更高;

代码实现:


class Solution {
    public List<String> generateParenthesis(int n) {
        LinkedList<String> list = new LinkedList<>();
        StringBuilder  sb = new StringBuilder();
        generateOne(list,sb,0,0,n);
        return list;
    }
    public void generateOne(List<String> list,StringBuilder sb, int leftCount, int rightCount,int n){
        if(leftCount >= n && rightCount >= n){ //搜索结束,保存结果
            list.add(sb.toString());
        }
        if(leftCount < n){ //下一个字符为 ( 的搜索分支
            sb.append("(");
            generateOne(list,sb,leftCount+1,rightCount,n);
            sb.deleteCharAt(sb.length()-1);
        }
        if(rightCount < leftCount){//下一个字符为 ) 的搜索分支
            sb.append(")");
            generateOne(list,sb,leftCount,rightCount+1,n);
            sb.deleteCharAt(sb.length()-1);
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值