第一个思路(错误的~):假设递归函数返回 n - 1对括号组成的所有合法字符串,将其看做整体A,则 所求 n 对括号组成的合法字符串是所有()A,A(),(A)。这个思路对于n<=3是可行的,一旦 n > 4,就会漏解,比如对于 n=4, 会漏掉(())(())
第二个思路:递归构造出合法字符串,初始时拥有 n 个左右括号,递归的每一层根据当前资源情况添加一个左括号或者右括号后继续递归,递归结束条件是 n 个左右括号正好使用完。
对于每次递归,仅当剩余左括号数 < 剩余右括号数时本次可添加右括号,否则已构成的字符串中没有左括号可与新加上右括号匹配。
这是一个经典的卡特兰数问题,可参考wikipedia:
https://zh.wikipedia.org/wiki/%E5%8D%A1%E5%A1%94%E5%85%B0%E6%95%B0
public class Solution { // Method 2 List<String> result = new ArrayList<String>(); public List<String> generateParenthesis1(int n) { result.clear(); recur(n, n, new StringBuilder()); return result; } public void recur(int left, int right, StringBuilder item) { if (left == 0 && right == 0) { result.add(item.toString()); return; } if (left < right) { item.append(')'); recur(left, right - 1, item); item.deleteCharAt(item.length() - 1); } if (left > 0) { item.append('('); recur(left - 1, right, item); item.deleteCharAt(item.length() - 1); } } // Method 1: Fail @ n ==4, miss "(())(())" public Set<String> recur(int n) { Set<String> result = new HashSet<String>(); if (n == 1) { result.add("()"); return result; } Set<String> sub = recur(n - 1); for (String str : sub) { result.add("(" + str + ")"); result.add("()" + str); result.add(str + "()"); } return result; } }