代码随想录_回溯系列
leetcode51 八皇后问题
皇后会对同一行、同一列、同一左斜对角线、同一右斜对角线的皇后发起攻击。
使用point数组来记录每个皇后放置的位置,使用canUse来确定该行哪个位置能放置皇后。
现在有两个皇后,其坐标分别为(x1,y1),(x2,y2)
同一左斜对角线的数学规律:x1-y1 = x2-y2
同一右斜对角线的数学规律:x1+y1 = x2+y2
class Solution {
private List<List<String>> ans = new ArrayList();
private void backtracking(int depth, int n, int point[]) {
if(depth == n) {
List<String> path = new ArrayList();
for(int i = 0; i < n; i++) {
char[] initialStr = new char[n];
Arrays.fill(initialStr, '.');
initialStr[point[i]] = 'Q';
path.add(String.valueOf(initialStr));
}
ans.add(path);
return;
}
boolean[] canUse = new boolean[n];
Arrays.fill(canUse, true);
for(int i = 0; i < depth; i++) {
// col
canUse[point[i]] = false;
// right diagonal
int diagonal = point[i] + i - depth;
if(0 <= diagonal && diagonal < n) canUse[diagonal] = false;
// left diagonal
diagonal = depth - i + point[i];
if(0 <= diagonal && diagonal < n) canUse[diagonal] = false;
}
for(int i = 0; i < n; i++) {
if(canUse[i] == true) {
point[depth] = i;
canUse[i] = false;
backtracking(depth+1, n, point);
canUse[i] = true;
point[depth] = -1;
}
}
}
public List<List<String>> solveNQueens(int n) {
// 第i行上放置的数字
int[] point = new int[n];
Arrays.fill(point, -1);
backtracking(0, n, point);
return ans;
}
}
leetcode37 解数独
class Solution {
private boolean isValid(int m, int n, char k, char[][] board) {
for(int j = 0; j < 9; j++) {
if(board[m][j] == k) return false;
}
for(int i = 0; i < 9; i++) {
if(board[i][n] == k) return false;
}
int startR = (m / 3) * 3;
int startC = (n / 3) * 3;
for(int i = startR; i < startR + 3; i++) {
for(int j = startC; j < startC + 3; j++) {
if(board[i][j] == k) return false;
}
}
return true;
}
private boolean backtracking(char[][] board) {
for(int i = 0; i < 9; i++) {
for(int j = 0; j < 9; j++) {
if(board[i][j] != '.') continue;
for(char k = '1'; k <= '9'; k++) {
if(isValid(i,j,k,board) == true) {
board[i][j] = k;
if(backtracking(board)) return true;
board[i][j] = '.';
}
}
return false;
}
}
return true;
}
public void solveSudoku(char[][] board) {
backtracking(board);
return;
}
}