LC.P37[解数独]

方法一:回溯

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
class Solution {
// 表示 行、列、3*3 的方格的数字是否被使用过
boolean[][] row = new boolean[9][10];
boolean[][] col = new boolean[9][10];
boolean[][][] box = new boolean[3][3][10];
char[][] board;

public void solveSudoku(char[][] board) {
this.board = board;
for (int i = 0; i < 9; ++i) {
for (int j = 0; j < 9; ++j) {
if (board[i][j] != '.') {
int x = board[i][j] - '0';
row[i][x] = true;
col[j][x] = true;
box[i / 3][j / 3][x] = true;
}
}
}
dfs(0, 0);
}

// 按行填充
private boolean dfs(int x, int y) {
if (y == 9) return dfs(x + 1, 0);
if (x == 9) return true;
// 当前位置非空,尝试填充下一个数字
if (board[x][y] != '.') return dfs(x, y + 1);
for (int i = 1; i <= 9; ++i) {
// 数字 i 未被使用过
if (!row[x][i] && !col[y][i] && !box[x / 3][y / 3][i]) {
board[x][y] = (char) (i + '0');
row[x][i] = col[y][i] = box[x / 3][y / 3][i] = true;
if (dfs(x, y + 1)) {
break;
} else {
board[x][y] = '.';
row[x][i] = col[y][i] = box[x / 3][y / 3][i] = false;
}
}
}
return board[x][y] != '.';
}
}
  • 时间复杂度:$O(1)$,棋盘固定大小为 $9 \times 9$
  • 空间复杂度:$O(1)$