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.
这个问题初看复杂,时候考虑过递归呢?我们可以把这个问题看做是一个深度优先的遍历过程。如果某个位置有几种可能性,对于每一种可能性递归调用,直到找到可行的解法。
class Solution {
public:
struct Node {
int x, y;
Node(int _x, int _y) : x(_x), y(_y) {
}
};
int sz;
vector<Node> empties;
bool dfs(vector<vector<char> > &board, int depth) {
if(depth >= sz) return true;
int ii = empties[depth].x;
int jj = empties[depth].y;
int flags[10] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
// Record existing values of the same row
for(int kk = 0; kk < 9; kk ++) {
if(board[ii][kk] != '.')
flags[board[ii][kk] - '0'] = 0;
}
// Record existing values of the same column
for(int kk = 0; kk < 9; kk ++) {
if(board[kk][jj] != '.')
flags[board[kk][jj] - '0'] = 0;
}
// Record existing values of the same block
int blocki = (ii / 3) * 3;
int blockj = (jj / 3) * 3;
for(int kk = 0; kk < 3; kk ++) {
for(int mm = 0; mm < 3; mm ++) {
if(board[blocki + kk][blockj + mm] != '.')
flags[board[blocki + kk][blockj + mm] - '0'] = 0;
}
}
// For each possible value, try to use depth first recursively searching.
for(int kk = 1; kk < 10; kk ++) {
if(flags[kk] == 0) continue;
board[ii][jj] = '0' + kk;
if(dfs(board, depth + 1))
return true;
board[ii][jj] = '.';
}
return false;
}
void solveSudoku(vector<vector<char> > &board) {
// Use empties to store all empty ones.
for(int ii = 0; ii < 9; ii ++) {
for(int jj = 0; jj < 9; jj ++) {
if(board[ii][jj] == '.') {
Node node(ii, jj);
empties.push_back(node);
}
}
}
sz = empties.size();
dfs(board, 0);
}
};