思路
我们可以生成所有,字符构成的序列,然后我们检查每一个是否有效即可。
算法
为了生成所有序列,我们可以使用递归。长度为 n 的序列就是在长度为 n−1的序列前加一个 "(" 或")"
输出的结果如下 ['((((', '((()', '(()(', '(())', '()((', '()()', '())(', '()))', ')(((', ')(()', ')()(', ')())', '))((', '))()', ')))(', '))))'] 我们发现有一些结果是我们不需要的,比如((((,比如)))) 观察不需要的括号特点,((((实际上已经超过n了,我们生成同一方向的括号只需要n个即可,在生成的时候我们要限制住左括号与右括号生成的数量
这时我增加了left与right参数,分别代表左括号与右括号的数量,每生成一个我就增加一个
class Solution {
List<String> list = new ArrayList<String>();
public List<String> generateParenthesis(int n) {
if(n <= 0){
return null;
}
def("",0,0,n);
return list;
}
public void def(String path,int left,int right,int n){
//递归出口1,①当前左括号数目大于n②当前右括号大于左括号数目,
//这两个情况一定是错误情况,故直接退出,EG:)((就直接错误。
if(left > n || right >left) return;
//递归的出口2,当前的路径长度等于2n,添加
if(path.length() == n*2){
list.add(path);
return;
}
//递归入口,跟满二叉树一样,中序遍历,每进行到最后一步就返回
def(path+"(",left+1,right,n);
def(path+")",left,right+1,n);
}
}
时间复杂度:O(2^2n * n)
空间复杂度:O(n),除了答案数组之外,我们所需要的空间取决于递归栈的深度,每一层递归函数需要 O(1)的空间,最多递归 2n 层。