解决一个回溯问题,实际上就是一个决策树的遍历过程
你只需要思考 3 个问题:
1、路径:也就是已经做出的选择。
2、选择列表:也就是你当前可以做的选择。
3、结束条件:也就是到达决策树底层,无法再做选择的条件。
回溯算法框架:
result = []
def backtrack(路径, 选择列表):
if 满足结束条件:
result.add(路径)
return
for 选择 in 选择列表:
做选择
backtrack(路径, 选择列表)
撤销选择
其核心就是 for 循环里面的递归,在递归调用之前「做选择」,在递归调用之后「撤销选择」
从根遍历,记录路径上的数字
全排列问题 leetcode 46
// 存储全排列的结果
List<List<Integer>> res = new LinkedList<>();
public List<List<Integer>> permute(int[] nums) {
// 记录路径
LinkedList<Integer> track = new LinkedList<>();
backtrack(nums, track);
return res;
}
// 回溯算法框架
private void backtrack(int[] nums, LinkedList<Integer> track) {
// 到大叶子节点,将路径装入结果列表
if (track.size() == nums.length) {
res.add(new LinkedList(track));
return;
}
for (int i = 0; i < nums.length; i++) {
// 排除不合法的选择
if (track.contains(nums[i])) {
continue;
}
// 做选择
track.add(nums[i]);
// 进入下一层决策树
backtrack(nums, track);
// 取消选择
System.out.println(track.removeLast());
// track.removeLast();
}
}
N皇后问题leetcode 51
List<List<String>> res2 = new LinkedList<>();
public List<List<String>> solveNQueens(int n) {
char[][] board = new char[n][n];
for (char[] c : board) {
Arrays.fill(c, '.');
}
backtrack(n, 0, board);
return res2;
}
private void backtrack(int n, int row, char[][] board) {
if (row == n) {
res2.add(turnToString(board));
return;
}
for (int col = 0; col < n; col++) {
if (isValid(row, col, n, board)) {
board[row][col] = 'Q';
backtrack(n, row + 1, board);
board[row][col] = '.';
} else {
continue;
}
}
}
boolean isValid(int row, int col, int n, char[][] chessboard) {
for (int i = 0; i < row; i++) {
if (chessboard[i][col] == 'Q') {
return false;
}
}
for (int i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--) {
if (chessboard[i][j] == 'Q') {
return false;
}
}
for (int i = row - 1, j = col + 1; i >= 0 && j < n; i--, j++) {
if (chessboard[i][j] == 'Q') {
return false;
}
}
return true;
}
List<String> turnToString(char[][] chessboard) {
List<String> list = new ArrayList<>();
for (char[] chess : chessboard) {
StringBuilder sbd = new StringBuilder();
for (char c : chess) {
sbd.append(c);
}
list.add(sbd.toString());
}
return list;
}