题目描述
Write a program to solve a Sudoku puzzle by filling the empty cells.
Empty cells are indicated by the character '.'
.
You may assume that there will be only one unique solution.
A sudoku puzzle...
...and its solution numbers marked in red.
求解数独。解题思路
用回溯法我们只要检查新加入的值能否在行、列以及小方块里有效即可。
代码
public static void solveSudoku(char[][] board) {
internalSolveSudoku(board);
}
/**
* 回溯求解数独问题
*
* @param board
* @return
*/
public static boolean internalSolveSudoku(char[][] board) {
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[0].length; j++) {
if (board[i][j] == '.') {
for (int k = 1; k <= 9; k++) {
board[i][j] = (char) ('0' + k);
if (isValid(board, i, j)) {
// 递归
if (internalSolveSudoku(board)) {
return true;
}
}
// 回溯
board[i][j] = '.';
}
return false;
}
}
}
return true;
}
/**
* 判断一个数字在当前位置是否合法
*
* @param board
* @param row
* @param column
* @return
*/
public static boolean isValid(char[][] board, int row, int column) {
int cellStartX = (row / 3) * 3;
int cellStartY = (column / 3) * 3;
char c = board[row][column];
for (int i = 0; i < board.length; i++) {
if (i != row && board[i][column] == c) {
return false;
}
}
for (int i = 0; i < board[0].length; i++) {
if (i != column && board[row][i] == c) {
return false;
}
}
for (int i = cellStartX; i < cellStartX + 3; i++) {
for (int j = cellStartY; j < cellStartY + 3; j++) {
if (i != row && j != column && board[i][j] == c)
return false;
}
}
return true;
}