DFS的题目,为了简化逻辑,我采用的是通过判断是否为'.'来判定是否往下继续搜索,所以每一次DFS时 都会从头往下找第一个不是'.'的位置,可能开销大一点,但是程序会
看起来更加简洁。
ref: http://blog.csdn.net/fightforyourdream/article/details/16916985
ref: http://blog.csdn.net/zxzxy1988/article/details/8586289
代码如下:
public class Solution {
// ref: http://blog.csdn.net/fightforyourdream/article/details/16916985
public void solveSudoku(char[][] board) {
if (board == null || board.length != 9 || board[0].length != 9) {
return;
}
rec(board);
}
public boolean rec(char[][] board) {
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
if (board[i][j] == '.') {
for (int k = 1; k <= 9; k++) {
board[i][j] = (char)('0' + k);
if (isValid(board, i, j) && rec(board)) { // if this number is valid, just continue to DFS.
return true;
}
}
board[i][j] = '.';
return false; // All the posibility is invalid, then just return false.
}
}
}
return true;
}
public boolean isValid(char[][] b, int x, int y) {
for (int i = 0; i < 9; i++) {
if (i != x && b[i][y] == b[x][y]) {
return false;
}
}
for (int j = 0; j < 9; j++) {
if (j != y && b[x][j] == b[x][y]) {
return false;
}
}
for (int i = x/3*3; i < x/3*3 + 3; i++) {
for (int j = y/3*3; j < y/3*3 + 3; j++) {
if (b[i][j] == b[x][y] && (i != x || j != y)) {
return false;
}
}
}
return true;
}
}
考虑到每次DFS都要从头扫到第一是'.' 的位置,我们可以多加2个参量来记录当前扫描的位置。代码经过refacter之后如下:
public class Solution {
// ref: http://blog.csdn.net/fightforyourdream/article/details/16916985
public void solveSudoku(char[][] board) {
if (board == null || board.length != 9 || board[0].length != 9) {
return;
}
rec(board, 0, 0);
}
public boolean rec(char[][] board, int x, int y) {
if (x >= 9) {
return true;
}
if (y >= 9) {
x++;
y = 0;
return rec(board, x, y);
}
if (board[x][y] == '.') {
for (int k = 1; k <= 9; k++) {
board[x][y] = (char)('0' + k);
if (isValid(board, x, y) && rec(board, x, y + 1)) { // if this number is valid, just continue to DFS.
return true;
}
}
board[x][y] = '.';
return false; // All the posibility is invalid, then just return false.
} else {
return rec(board, x, y + 1);
}
}
public boolean isValid(char[][] b, int x, int y) {
for (int i = 0; i < 9; i++) {
if (i != x && b[i][y] == b[x][y]) {
return false;
}
}
for (int j = 0; j < 9; j++) {
if (j != y && b[x][j] == b[x][y]) {
return false;
}
}
for (int i = x/3*3; i < x/3*3 + 3; i++) {
for (int j = y/3*3; j < y/3*3 + 3; j++) {
if (b[i][j] == b[x][y] && (i != x || j != y)) {
return false;
}
}
}
return true;
}
}