- 回溯将 ans、combine定义为全局变量是可以的,在add时new一个新的比较保险。
- 典型的相关题型如下
1、22. 括号生成
/**
* 括号生成
* ans、combine放在函数中
*/
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
String string = bufferedReader.readLine();
int n = Integer.parseInt(string);
ArrayList<String> ansCombines = new ArrayList<>();
backtrack(ansCombines, new StringBuilder(), n, 0, 0);
System.out.println(ansCombines);
}
public static void backtrack(List<String> ans, StringBuilder combine, int max, int open, int close){
if (combine.length() == max * 2){
ans.add(new String(combine));
return;
}
if (open < max){
combine.append('(');
backtrack(ans, combine, max, open + 1, close);
combine.deleteCharAt(combine.length() - 1);
}
if (close < open){
combine.append(')');
backtrack(ans, combine, max, open, close + 1);
combine.deleteCharAt(combine.length() - 1);
}
}
}
/**
* 所有子集
*/
public class Main1 {
private static ArrayList<List<Integer>> ans = new ArrayList<>();
private static ArrayList<Integer> combine= new ArrayList<>();
public static void main(String[] args) throws IOException {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
String string = bufferedReader.readLine();
String[] s = string.split(" ");
int length = s.length;
int[] ints = new int[length];
for (int i = 0; i < length; i++) {
ints[i] = Integer.parseInt(s[i]);
}
backtrack(ints, 0);
System.out.println(ans);
}
public static void backtrack(int[] nums, int index){
int length = nums.length;
if (index == length){
ans.add(new ArrayList<>(combine));
return;
}
//直接走
backtrack(nums, index + 1);
//加上这个再走
combine.add(nums[index]);
backtrack(nums, index + 1);
combine.remove(combine.size() - 1);
}
}
/**
* 无重复字符串的排列组合
*/
public class Main2 {
private static ArrayList<String> ans = new ArrayList<>();
private static StringBuilder combine = new StringBuilder();
private static boolean vis[];
public static void main(String[] args) throws IOException {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
String string = bufferedReader.readLine();
char[] chars = string.toCharArray();
int length = chars.length;
vis = new boolean[length];
backtrack(chars);
System.out.println(ans);
}
public static void backtrack(char[] chars){
int length = chars.length;
if (combine.length() == length){
ans.add(new String(combine));
return;
}
for (int i = 0; i < length; i++) {
if (vis[i]){
continue;
}
//通过回溯来改变位置
combine.append(chars[i]);
vis[i] = true;
backtrack(chars);
vis[i] = false;
combine.deleteCharAt(combine.length() - 1);
}
}
}
/**
* 有重复字符串的排列组合
*/
public class Main3 {
private static ArrayList<String> ans = new ArrayList<>();
private static StringBuilder combine = new StringBuilder();
private static boolean vis[];
public static void main(String[] args) throws IOException {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
String string = bufferedReader.readLine();
char[] chars = string.toCharArray();
int length = chars.length;
vis = new boolean[length];
backtrack(chars);
System.out.println(ans);
}
public static void backtrack(char[] chars){
int length = chars.length;
if (combine.length() == length){
ans.add(new String(combine));
return;
}
for (int i = 0; i < length; i++) {
//在此做一些改变!!!
if (vis[i] || (i > 0 && chars[i] == chars[i - 1] && !vis[i - 1])){
continue;
}
//通过回溯来改变位置
combine.append(chars[i]);
vis[i] = true;
backtrack(chars);
vis[i] = false;
combine.deleteCharAt(combine.length() - 1);
}
}
}