题目来源:力扣
题目描述:
括号。设计一种算法,打印n对括号的所有合法的(例如,开闭一一对应)组合。
说明:解集不能包含重复的子集。
例如,给出 n = 3,生成结果为:
[
“((()))”,
“(()())”,
“(())()”,
“()(())”,
“()()()”
]
审题:
考虑逐位添加字符构建括号字符串,每一步我们需要判断是否可以添加左括号,是否可以添加右括号.分析合法括号字符串的规律不难发现,如果左右括号均有剩余,则仅当左括号数量大于右括号时,可以添加右括号,否则只能添加左括号.实际上,如果我们将每一步的选择视为树节点的左子节点与右子节点,则我们可以构建一棵括号树,向左表示下一步添加左括号,向右表示下一步添加右括号.则该问题转化为在所有括号排列中,打印可行路径.
分析该问题可以发现,只要到达可行路径的底部,则我们即找到一个可行的括号构造方式,该问题并不涉及回溯步骤,因此我个人并不觉的这种解法为回溯算法.但力扣将该题目的标签设置为回溯算法,很多题解中也称这种做法为回溯算法,个人感觉不妥,这仅仅只是一个标准的深度优先搜索.
java算法:
class Solution {
//穷举所有可能集合
//每次添加完括号必须保证左括号数量大于等于右括号
private void _generateParenthesis(int n, int left, int right, String s, List<String> list){
if(left == n && right == n){
list.add(s);
return;
}
if(n-left > 0){//如果可以添加左括号
_generateParenthesis(n, left+1, right, s+"(", list);
}
if(left > right && n - right > 0){ //如果可以添加右括号
_generateParenthesis(n, left, right+1, s+")", list);
}
}
public List<String> generateParenthesis(int n) {
List<String> list = new LinkedList<>();
_generateParenthesis(n, 0, 0, "", list);
return list;
}
}