问题描述:
Write a program to solve aSudoku 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.
问题分析:
解数独问题,问题类似八皇后问题,采用回溯算法BackTracking;即向[i,j]尝试放入数字data,若满足数独规则,则继续进行下一步;若不满足,则回溯到上一步,重新进行遍历。
代码:
public class Solution {
public void solveSudoku(char[][] board) {
// 判断输入board是否合法
if(board == null || board.length == 0)
return;
solve(board);
}
// 回溯算法遍历解数独
private boolean solve(char[][] board) {
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[0].length; j++) {
// 填充空格处
if (board[i][j] == '.') {
for (char data = '1'; data <= '9'; data++) {
// 如果该data放入当前数组中合法
if (isValid(board, i, j,data)) {
board[i][j] = data;
// 判断填充后是否完成解数独
if (solve(board))
return true;
else // 否则,进行回溯,回到上一状态
board[i][j] = '.';
}
}
// 对应无解情况
return false;
}
}
}
return true;
}
// 判断新设定的数是否合法
private boolean isValid(char[][] board, int i, int j, char data) {
// 判断是否行有效
for (int row = 0; row < board.length; row++) {
if (board[row][j] == data)
return false;
}
// 判断是否列有效
for (int column = 0; column < board[0].length; column++) {
if (board[i][column] == data)
return false;
}
// 判断对角线元素是否有效
for (int row = i / 3 * 3; row < i / 3 * 3 + 3;row++) {
for (int column = j / 3 * 3; column < j / 3 * 3 +3; column++) {
if (board[row][column] == data)
return false;
}
}
return true;
}
}