剑指 Offer II 085. 生成匹配的括号(22. 括号生成)
题目:
思路:
【1】回溯的方式
【2】按括号序列的长度递归
任何一个括号序列都一定是由 '(' 开头,并且第一个 '(' 一定有一个唯一与之对应的 ')'。
这样一来,每一个括号序列可以用 (a)b 来表示,其中 a 与 b 分别是一个合法的括号序列(可以为空)。
那么,要生成所有长度为 2n 的括号序列,我们定义一个函数 generate(n)\ 来返回所有可能的括号序列。
那么在函数 generate(n) 的过程中:
我们需要枚举与第一个 '(' 对应的 ')' 的位置 2i+1;
递归调用 generate(i) 即可计算 a 的所有可能性;
递归调用 generate(n−i−1) 即可计算 bbb 的所有可能性;
遍历 a 与 b 的所有可能性并拼接,即可得到所有长度为 2n2n2n 的括号序列。
为了节省计算时间,我们在每次 generate(i) 函数返回之前,把返回值存储起来,
下次再调用 generate(i) 时可以直接返回,不需要再递归计算。
代码展示:
按括号序列的长度递归:
//时间7 ms击败11.46% //内存41.4 MB击败69.69% class Solution { ArrayList[] cache = new ArrayList[100]; public List<String> generate(int n) { if (cache[n] != null) { return cache[n]; } ArrayList<String> ans = new ArrayList<String>(); if (n == 0) { ans.add(""); } else { for (int c = 0; c < n; ++c) { for (String left: generate(c)) { for (String right: generate(n - 1 - c)) { ans.add("(" + left + ")" + right); } } } } cache[n] = ans; return ans; } public List<String> generateParenthesis(int n) { return generate(n); } }
回溯的方式:
//时间1 ms击败64.52% //内存41.8 MB击败16.31% class Solution { public List<String> generateParenthesis(int n) { List<String> res = new ArrayList<>(); if (n == 0) return res; dfs(n,0,new StringBuffer(),res); return res; } private void dfs(int left_b, int right_b, StringBuffer path, List<String> res) { if (left_b == 0 && right_b == 0) { res.add(path.toString()); return; } if (left_b > 0){ dfs(left_b - 1,right_b + 1,path.append("("),res); path.deleteCharAt(path.length()-1); } if (right_b > 0){ dfs(left_b,right_b - 1,path.append(")"),res); path.deleteCharAt(path.length()-1); } } } //直接用String更直观点 //时间1 ms击败75.56% //内存41.6 MB击败38.2% class Solution { public List<String> generateParenthesis(int n) { List<String> res = new ArrayList<>(); if (n == 0) return res; dfs(n,0,"",res); return res; } private void dfs(int left_b, int right_b, String path, List<String> res) { if (left_b == 0 && right_b == 0) { res.add(path); return; } if (left_b > 0){ dfs(left_b - 1,right_b + 1,path+"(",res); } if (right_b > 0){ dfs(left_b,right_b - 1,path+")",res); } } }