新博文地址:[leetcode]Sudoku Solver
Sudoku Solver
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.
Empty cells are indicated by the character '.'.
You may assume that there will be only one unique solution.
好了,最后一道题了,一直对数独特别害怕,不知道为啥,但是仔细看了这道题,貌似没啥难度,跟八皇后问题一样,典型的回溯算法,当然也可以用迭代实现,我同学用了迭代实现的,因此我就写了一个递归版本的,算法思想就是典型的DFS,因此这里不再啰嗦。
尴尬的是,DFS在找到一个结果的时候会继续回溯寻找下一个可能的结果,因此我又设置了一个全局变量来添加控制。这无疑让代码可读性变差,如果谁有更好的方法:找到一个解之后立马跳出整个递归过程,请告之
代码如下:
boolean over = false;
public void solveSudoku(char[][] board) {
if (board == null || board.length == 0
|| board.length != board[0].length || board.length % 9 != 0) {
return;
}
int height = board.length;
int width = board[0].length;
dfs(0, 0, board, height, width);
}
private void dfs(int row, int column, char[][] board, int height, int width) {
if(over) return;
if (row == board.length ) {
over = true;
return;
}
if (board[row][column] != '.' ) {
if (column < width - 1 && !over) {
dfs(row, column + 1, board, height, width);
} else if (column == width - 1 && !over) {
dfs(row + 1, 0, board, height, width);
}
} else {
for (char c = '1'; c <= '9' && !over; c++) {
if (!isConflict(c, row, column, board)) {
board[row][column] = c;
if (column < width - 1) {
dfs(row, column + 1, board, height, width);
} else if (column == width - 1) {
dfs(row + 1, 0, board, height, width);
}
}
}
if(!over)board[row][column] = '.';
}
}
private boolean isConflict(char num, int row, int column, char[][] board) {
int height = board.length;
int width = board[0].length;
for (int i = 0; i < width; i++) {
if (i != column && board[row][i] == num) {
return true;
}
}
for (int i = 0; i < height; i++) {
if (i != row && board[i][column] == num) {
return true;
}
}
int beginRow = (row / 3) * 3;
int endRow = beginRow + 2;
int beginColumn = (column / 3) * 3;
int endColumn = beginColumn + 2;
for (int i = beginRow; i <= endRow; i++) {
for (int j = beginColumn; j <= endColumn; j++) {
if (i == row && j == column)
continue;
if (board[i][j] == num)
return true;
}
}
return false;
}