力扣一题 22.括号生成

277 阅读2分钟

数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。

有效括号组合需满足:左括号必须以正确的顺序闭合。

image-20211103140905765.png

分析

关键字眼“所有可能的”,有这个关键词的题目都是要枚举所有可能的情况,枚举所有情况那么就可以采用暴力搜索的方法。再结合MAX(n)=8,那么采用dfs就不会出现超内存限制的情况了,直接开搞!

我们使用一个变量val来记录”左括号与右括号的数量查“即可,保证左括号的数量永远>=右括号的数量

代码

来人,上代码!

class Solution {
    List<String>res=new ArrayList();
    public List<String> generateParenthesis(int n) {
        helper("(",1,n);
        return res;
    }
​
    void helper(String str,int val,int n){
        if(str.length()==2*n){
            if(val==0) res.add(str);
            return;
        }
        if(val<n) helper(str+"(",val+1,n);
        if(val>0) helper(str+")",val-1,n);
    }
}

执行结果如下,执行用时2ms,但是只击败了22.80%的用户,说明还有优化点!

image-20211103141551019.png

优化

代码数量不多,所以优化点也很容易就可以看出来,就是在String进行“+”运算的地方

String的“+”运算的底层是通过StringBuilder的append()方法完成的,最后再调用了toString(),而其toString()的实现就是创建了一个新的String()对象返回

所以在上面代码的调用过程中,不断地new String对象,导致执行用时较高。那么我们使用char数组来代替String即可,这样就可以实现内存的共享,不用频繁地创建对象,只需要多维护一个idx下标变量即可

其实在算法题中,有很大一部分涉及到字符串相加的题都可以使用char数组来进行优化

代码

class Solution {
    List<String>res=new ArrayList();
    public List<String> generateParenthesis(int n) {
        char[]arr=new char[2*n];
        arr[0]='(';
        helper(arr,1,n,1);
        return res;
    }
​
    void helper(char[]arr,int val,int n,int idx){
        if(idx==arr.length){
            if(val==0) res.add(new String(arr));
            return;
        }
        if(val<n){
            arr[idx]='(';
            helper(arr,val+1,n,idx+1);
        } 
        if(val>0){
            arr[idx]=')';
            helper(arr,val-1,n,idx+1);
        } 
    }
}

执行结果

image-20211103142500711.png