Write a program to solve a Sudoku puzzle by filling the empty cells.
A sudoku solution must satisfy all of the following rules:
1-9
must occur exactly once in each row.1-9
must occur exactly once in each column.1-9
must occur exactly once in each of the 9 3x3
sub-boxes of the grid.Empty cells are indicated by the character '.'
.
A sudoku puzzle…
…and its solution numbers marked in red.
Note:
1-9
and the character '.'
.9x9
.编写一个程序,通过已填充的空格来解决数独问题。
一个数独的解法需遵循如下规则:
数字 1-9 在每一行只能出现一次。 数字 1-9 在每一列只能出现一次。 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。 空白格用 ‘.’ 表示。
题的解法类似于36.Valid Sudoku;不同之处在于36题验证Sudoku的有效性,其中包括‘.’表示的空白,而且不需要对其进行填充;这道题除了进行有效性验证外,还需要对Sudoku进行求解。
借助上一题的解法,先对当前空白处进行尝试性填充,如果填充有效[使用36题的方法],则继续;如果无效,则重置为空白;不断递归,直到找到解或者处于没有解的情况[题目中表明一定存在一个解,所以最后返回时一定找到了解]。
步骤:
完整代码:
class Solution {
public:
void solveSudoku(vector<vector<char>>& board) {
if (board.empty() || board.size() != 9 || board[0].size() != 9)
return;
dfs(board, 0, 0);
}
bool isValid(vector<vector<char>>& board, int i, int j){
for (int t=0; t< 9; t++){
if (t != j && board[i][t] == board[i][j]) return false;
if (t != i && board[t][j] == board[i][j]) return false;
}
int row = i / 3 * 3, col = j / 3 * 3;
for (int m=row; m< row+3; m++){
for (int n=col; n< col+3; n++){
if (m!=i && n!=j && board[m][n] == board[i][j])
return false;
}
}
return true;
}
bool dfs(vector<vector<char>>& board, int i, int j){
if (i >= 9) return true;
if (j >= 9) return dfs(board, i+1, 0);
if (board[i][j] == '.'){
for (char t='1'; t<= '9'; t++){
board[i][j] = t;
if (isValid(board, i, j)){
if (dfs(board, i, j+1)) return true;
}
board[i][j] = '.';
}
}
else
return dfs(board, i, j+1);
return false;
}
};