【题目】
每一行、每一列、每个3*3的格子里只能出现一次1~9。
【思路】
参考了思路,附加了解释。
dfs遍历所有非空格子,n是已经填好的个数。
初始化条件。n=81,都填了,返回结束。对于已经填好的b[x][y] != '.'跳过,到下一个。
xy的设计保证先行后列填写。
if (n == 81) return true; int x = n / 9; int y = n % 9; if (b[x][y] != '.') return dfs(b, n + 1);
开始填数字,validate(b, x, y) && dfs(b, n + 1)共同确认是否填对。
for (int i = 0; i < 9; i++) { b[x][y] = (char)('1' + i);//开始试数1~9 if (validate(b, x, y) && dfs(b, n + 1)) //试填后进行validate检验+填下一个n+1数,成功返true。 return true; b[x][y] = '.';//否则擦除尝试,return false。 }
validate函数,check每一行、每一列、每3*3的格子。
public boolean validate(char[][] b, int x, int y) { for (int i = 0; i < 9; i++) { if (i != x && b[i][y] == b[x][y]) return false; if (i != y && b[x][i] == b[x][y]) return false; } int r = x / 3 * 3;//判断在哪个3*3的格子里 int c = y / 3 * 3; for (int i = r; i < r + 3; i++) { for (int j = c; j < c + 3; j++) { if (i == x && j == y) continue; if (b[i][j] == b[x][y]) return false; } } return true; }
【代码】
class Solution { public void solveSudoku(char[][] board) { dfs(board, 0); } public boolean dfs(char[][] b, int n) { if (n == 81) return true; int x = n / 9; int y = n % 9; if (b[x][y] != '.') return dfs(b, n + 1); for (int i = 0; i < 9; i++) { b[x][y] = (char)('1' + i); if (validate(b, x, y) && dfs(b, n + 1)) return true; b[x][y] = '.'; } return false; } public boolean validate(char[][] b, int x, int y) { for (int i = 0; i < 9; i++) { if (i != x && b[i][y] == b[x][y]) return false; if (i != y && b[x][i] == b[x][y]) return false; } int r = x / 3 * 3;//判断在哪个3*3的格子里 int c = y / 3 * 3; for (int i = r; i < r + 3; i++) { for (int j = c; j < c + 3; j++) { if (i == x && j == y) continue; if (b[i][j] == b[x][y]) return false; } } return true; } }