题目来源:https://leetcode.com/problems/sudoku-solver/
问题描述
37. Sudoku Solver
Hard
Write a program to solve a Sudoku puzzle by filling the empty cells.
A sudoku solution must satisfy all of the following rules:
- Each of the digits 1-9 must occur exactly once in each row.
- Each of the digits 1-9 must occur exactly once in each column.
- Each of the the digits 1-9 must occur exactly once in each of the 9 3x3 sub-boxes of the grid.
Empty cells are indicated by the character '.'.
Note:
- The given board contain only digits 1-9and the character '.'.
- You may assume that the given Sudoku puzzle will have a single unique solution.
- The given board size is always 9x9.
------------------------------------------------------------
题意
给定一个部分填充的数独,要求完成数独的填充。
------------------------------------------------------------
思路
解空间DFS. (好久没做搜索的题了,回溯的地方想的不是很清楚,卡了好久T_T)
具体来说,每个‘.’位置都可以放置‘1’到‘9’,总共n个‘.’位置产生9^n种可能,构成本问题的解空间。采用深度优先搜索一是因为只要找到一个可行解,二是因为方便在解空间回溯,从而可以在原数独数组上操作,不用复制原数组的备份。解空间DFS从(0, 0)位置到(8, 8)位置对所有的‘.’遍历‘1’到‘9’每一种可能,遍历时如果当前位置可行,则先向后判断直到失败回溯或全部填完找到可行解。具体实现细节请看代码。
------------------------------------------------------------
代码
class Solution {
private boolean[][] COL, ROW, BLOCK;
private void init(char[][] board)
{
COL = new boolean[9][9];
ROW = new boolean[9][9];
BLOCK = new boolean[9][9];
int i, j, v;
char ch = 0;
for (i=0; i<9; i++)
{
for (j=0; j<9; j++)
{
ch = board[i][j];
if (ch != '.')
{
v = Character.getNumericValue(ch) - 1;
COL[j][v] = true;
ROW[i][v] = true;
BLOCK[i/3*3+j/3][v] = true;
}
}
}
}
public void solveSudoku(char[][] board) {
init(board);
dfs(board, 0, 0);
}
private boolean dfs(char[][] board, int x, int y)
{
int v, xx, yy;
if (x == 9 && y == 0)
{
return true; // end of 9x9 board
}
if (y == 8)
{
xx = x + 1;
yy = 0;
}
else
{
xx = x;
yy = y + 1;
}
char ch = board[x][y];
if (ch == '.')
{
for (v=0; v<9; v++)
{
if (!COL[y][v] && !ROW[x][v] && !BLOCK[x/3*3+y/3][v])
{
board[x][y] = (char)(v + (int)'1');
COL[y][v] = true;
ROW[x][v] = true;
BLOCK[x/3*3+y/3][v] = true;
if(!dfs(board, xx, yy))
{
board[x][y] = '.';
COL[y][v] = false;
ROW[x][v] = false;
BLOCK[x/3*3+y/3][v] = false;
}
else
{
return true;
}
}
}
return false;
}
else
{
return dfs(board, xx ,yy);
}
}
}