有効な数独
トピック
2 次元配列で表された Sudoku が与えられた場合、その Sudoku が有効な
リンクであるかどうかを判断します。
一連の考え
3 つのブール型 2 次元配列を使用して、数値 j が i 番目の行、i 番目の列、および i 番目の 9 マスのグリッドに現れるかどうかを示します。特定の数値が特定の行、列、または 9 に繰り返し現れる場合- 正方形のグリッド、数独には解決策がありません。トラバースは成功しました。すべてのグリッドに解決策があります。
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;
}
}
数独へのユニークな解決策
トピック
2 次元配列で表される Sudoku を指定すると、その Sudoku の解決策が返されます。タイトルにより、Sudoku が固有の解決策
リンクを持つことが保証されます。
一連の考え
上の質問と同じように、3 つの 2 次元配列を使用して、数値 j が i 行目、i 列目、i 番目の 9 正方形グリッドに現れるかどうかを記録し、グリッドを 1 つずつ走査してみます。各グリッドに 1 から 9 までの 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;
}
}
}