题目
回溯
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Main {
public static void main(String[] args) {
Main main = new Main();
int [] nums = new int[] {-1, 2, 1, -4};
main.generateParenthesis(3);
}
int n = 0;
List<String> ans = new ArrayList<>();
String [] choice = new String[2];
public List<String> generateParenthesis(int n) {
this.n = n;
choice[0] = "(";
choice[1] = ")";
huisu("", 0 , 0);
return ans;
}
public void huisu(String path, int leftParenthesisNum, int rightParenthesisNum) {
if (leftParenthesisNum == n && leftParenthesisNum == rightParenthesisNum) {
ans.add(path);
return;
}
// 选择列表
for (int i = 0; i < 2; i ++) {
// 作出选择
if (i == 0 && leftParenthesisNum == n) {
continue;
}
if (i == 1 && rightParenthesisNum == leftParenthesisNum) {
continue;
}
path = path + choice[i];
if (i == 0) {
huisu(path, leftParenthesisNum + 1, rightParenthesisNum);
} else {
// 添加右括号的前提是
if (rightParenthesisNum < leftParenthesisNum) {
huisu(path, leftParenthesisNum, rightParenthesisNum + 1);
}
}
// 撤销选择
path = path.substring(0, path.length() - 1);
}
}
}
基本思路
-
遇见题目不要慌, 它问你字符串一共有哪些组成的可能, 和问你在方格里左上到右下的路径, 其实没啥差别, 都是从一个起点开始, 然后做一次选择, 最后选择结束, 得到一个可行的结果
-
根据题目, 需要得到n对括号, 不能存在无用的符号.
-
根据括号的特点, (1) 先有左括号, 才有右括号 (2) 有几个左括号, 就有几对括号 (3) 任何一个时刻, 右括号的数量, 不能超过左括号.
-
根据回溯的思想, 每次只有两个选择, 添加左括号还是右括号, 然后根据n, 左括号数量, 右括号数量来判断是否能选择, 然后递归, 然后撤销选择