题目地址:
解数独。DFS回溯+剪枝。代码如下:
public class Solution {
public void solveSudoku(char[][] board) {
dfs(board, 0);
}
// 表示正在尝试pos这个位置能填什么数
private boolean dfs(char[][] board, int pos) {
// 略过'.'
while (pos < 81 && board[pos / 9][pos % 9] != '.') {
pos++;
}
// 如果pos == 81,说明已经安全到达了数独最后一个数字之后,也就是已经找到了一个解,返回true
if (pos == 81) {
return true;
}
// 枚举当前位置的数字
for (int i = 1; i <= 9; i++) {
// 开始做尝试
board[pos / 9][pos % 9] = (char) ('0' + i);
// 如果满足条件,就枚举下一个数字,如果找到解了,返回true,不再枚举
if (check(board, pos) && dfs(board, pos + 1) {
return true;
}
// 如果没找到,当前位置要恢复原状,继续找解
board[pos / 9][pos % 9] = '.';
}
// 没找到,返回false
return false;
}
private boolean check(char[][] board, int pos) {
int row = pos / 9, col = pos % 9;
for (int i = 0; i < 9; i++) {
if (board[row][i] == board[row][col] && i != col) {
return false;
}
if (board[i][col] == board[row][col] && i != row) {
return false;
}
}
int i = row / 3 * 3, j = col / 3 * 3;
for (int k = 0; k < 3; k++) {
for (int l = 0; l < 3; l++) {
if (board[i + k][j + l] == board[row][col] && i + k != row && j + l != col) {
return false;
}
}
}
return true;
}
}