原文:
Implement an algorithm to print all valid (e.g., properly opened and closed) combinations of n-pairs of parentheses.
EXAMPLE:
input: 3 (e.g., 3 pairs of parentheses)
output: ((())), (()()), (())(), ()(()), ()()()
译文:
实现一个算法打印出n对括号的有效组合。
例如:
输入:3 (3对括号)
输出:((())), (()()), (())(), ()(()), ()()()
思路:
对于括号的组合,要考虑其有效性。比如说,)(, 它虽然也是由一个左括号和一个右括号组成,但它就不是一个有效的括号组合。 那么,怎样的组合是有效的呢?对于一个左括号,在它右边一定要有一个右括号与之配对, 这样的才能是有效的。所以,对于一个输出,比如说(()()), 从左边起,取到任意的某个位置得到的串,左括号数量一定是大于或等于右括号的数量, 只有在这种情况下,这组输出才是有效的。我们分别记左,右括号的数量为left和right, 如下分析可看出,(()())是个有效的括号组合。
(, left = 1, right = 0
((, left = 2, right = 0
((), left = 2, right = 1
(()(, left = 3, right = 1
(()(), left = 3, right = 2
(()()), left = 3, right = 3
对于中间位置,剩余括号的情况必定是右括号大于或者等于左括号的数量,不可能出现左括号大于右括号情况
可以当前位置分别添加左括号或者右括号,剩余位置使用递归调用,递归出口分别是:
1、当左右括号都使用完毕,则出口输出
2、出现右括号少于左括号,则出现错误,直接返回
package chapter_8_Recursion;
/**
*
* 实现一个算法打印出n对括号的有效组合。
*
*/
public class Question_8_5 {
public static void printAllCombinations(int left, int right, char[] result, int index) {
// 剩余括号一定是右括号多余或者等于左括号,否则不可能,直接返回
if(right< left) {
return;
}
// 左右括号都使用完毕,则直接返回
if(left == 0 && right == 0) {
System.out.println(new String(result) + ", ");
return;
}
// 当前添加左括号
if(left > 0) {
result[index] = '(';
printAllCombinations(left-1, right, result, index+1);
}
// 当前添加右括号
if(right > 0) {
result[index] = ')';
printAllCombinations(left, right-1, result, index+1);
}
}
public static void main(String args[]) {
int num = 3;
char[] result = new char[2 * num];
printAllCombinations(num, num, result, 0);
}
}