有效的数独
题目
给出一个二维数组表示的数独,判断该数独是否有效
链接
思路
用三个boolean二维数组,分别表示第i行、第i列、第i个九宫格中数字j是否出现,如果某数字在某一行、列、九宫格中反复出现,则数独无解;成功遍历所有格子则有解
class ValidSudoku {
// 二维数组[i][j]表示第i行、列、九宫格中j数是否出现
public static boolean isValidSudoku(char[][] board) {
boolean[][] row = new boolean[9][10]; // 0位置不使用
boolean[][] col = new boolean[9][10];
boolean[][] bucket = new boolean[9][10]; // bucket表示九宫格
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
// 求九宫格号
int bid = 3 * (i / 3) + (j / 3);
if (board[i][j] != '.') {
int num = board[i][j] - '0';
if (row[i][num] || col[j][num] || bucket[bid][num]) {
return false;
}
row[i][num] = true;
col[j][num] = true;
bucket[bid][num] = true;
}
}
}
return true;
}
}
数独的唯一解
题目
给出一个二维数组表示的数独,返回该数独的解,题目保证数独有唯一解
链接
思路
同上题一样,用三个二维数组记录第i行、第i列、第i个九宫格中数字j是否出现,然后逐个格子遍历,每个格子依次尝试1~9九个数字,遍历完后得到唯一解
class SudokuSolver {
public static void solveSudoku(char[][] board) {
boolean[][] row = new boolean[9][10]; // 0位置不使用,表示第i行j数字是否出现
boolean[][] col = new boolean[9][10]; // 表示第i列j数字是否出现
boolean[][] bucket = new boolean[9][10]; // 表示第i个九宫格j数字是否出现
initMaps(board, row, col, bucket);
process(board, 0, 0, row, col, bucket);
}
public static void initMaps(char[][] board, boolean[][] row, boolean[][] col, boolean[][] bucket) {
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
// 求九宫格号
int bid = 3 * (i / 3) + (j / 3);
if (board[i][j] != '.') {
int num = board[i][j] - '0';
row[i][num] = true;
col[j][num] = true;
bucket[bid][num] = true;
}
}
}
}
public static boolean process(char[][] board, int i, int j, boolean[][] row, boolean[][] col, boolean[][] bucket) {
if (i == 9) { // 到达终止位置
return true;
}
// 跳到下一个位置
int nexti = j != 8 ? i : i + 1;
int nextj = j != 8 ? j + 1 : 0;
if (board[i][j] != '.') {
return process(board, nexti, nextj, row, col, bucket);
} else {
int bid = 3 * (i / 3) + (j / 3);
for (int num = 1; num <= 9; num++) {
// 检验行、列、九宫格是否有重复数字
if (!row[i][num] && !col[j][num] && !bucket[bid][num]) {
row[i][num] = true;
col[j][num] = true;
bucket[bid][num] = true;
board[i][j] = (char) (num + '0');
if (process(board, nexti, nextj, row, col, bucket)) {
return true;
}
// 若尝试失败,则恢复现场
row[i][num] = false;
col[j][num] = false;
bucket[bid][num] = false;
board[i][j] = '.';
}
}
return false;
}
}
}