数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。
有效括号组合需满足:左括号必须以正确的顺序闭合。
分析
关键字眼“所有可能的”,有这个关键词的题目都是要枚举所有可能的情况,枚举所有情况那么就可以采用暴力搜索的方法。再结合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%的用户,说明还有优化点!
优化
代码数量不多,所以优化点也很容易就可以看出来,就是在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);
}
}
}
执行结果