[LeetCode] 22. Generate Parentheses
Given n
pairs of parentheses, write a function to generate all combinations of well-formed parentheses.
Example 1:
Input: n = 3 Output: ["((()))","(()())","(())()","()(())","()()()"]
Example 2:
Input: n = 1 Output: ["()"]
Constraints:
1 <= n <= 8
括号生成。
数字 n
代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。
题意是给一个数字 N,请返回由 N 对括号组成的所有可能的括号对。这是典型的backtracking回溯类的题目,基础题,一定要会。思路是创建一个 helper 函数表示当前拼接的情况 cur,用两个变量记录剩下的 left 括号数量和剩下的 right 括号数量。
- 任何时候,如果 left 剩下的比 right 多(说明递归过程中多加了right),一定不对,则跳出递归
- 如果 left 和 right 都用完则跳出递归函数并加入当前结果到结果集
- 如果 left 还有,则 left-- 继续递归
- 如果 right 还有,则 right-- 继续递归
时间O(4^n / sqrt(n)) - 这是卡特兰数的性质
空间O(4^n / sqrt(n))
Java实现
1 class Solution { 2 public List<String> generateParenthesis(int n) { 3 List<String> res = new ArrayList<>(); 4 helper(res, "", n, n); 5 return res; 6 } 7 8 private void helper(List<String> res, String cur, int left, int right) { 9 // 剩余的左括号数量不能大于右括号,如果大于,说明已经使用的右括号更多,是不合法的 10 if (left > right) { 11 return; 12 } 13 // 左右括号同时用完,加入结果集 14 if (left == 0 && right == 0) { 15 res.add(cur); 16 return; 17 } 18 // 左括号还未用完,就加一个,继续下面的递归 19 if (left > 0) { 20 helper(res, cur + "(", left - 1, right); 21 } 22 // 右括号还未用完,就加一个,继续下面的递归 23 if (right > 0) { 24 helper(res, cur + ")", left, right - 1); 25 } 26 } 27 }
JavaScript实现
1 /** 2 * @param {number} n 3 * @return {string[]} 4 */ 5 var generateParenthesis = function(n) { 6 let res = []; 7 var helper = function(left, right, cur) { 8 // corner case 9 if (left > right) { 10 return; 11 } 12 13 // normal case 14 if (left == 0 && right == 0) { 15 res.push(cur); 16 return; 17 } 18 if (left > 0) { 19 helper(left - 1, right, cur + '('); 20 } 21 if (right > 0) { 22 helper(left, right - 1, cur + ')'); 23 } 24 }; 25 helper(n, n, ''); 26 return res; 27 };