原题地址:https://leetcode-cn.com/problems/sudoku-solver/
dfs回溯法。
不断用1到9尝试未填入的地方。假如有某处无法填入,就把此处重新变为'.'(未填入状态),并且回溯。
在使用递归时要仔细,注意递归中参数的变化。
class Solution {
public:
void solveSudoku(vector<vector<char>>& board) {
dfs(board, 0, 0);
}
void dfs(vector<vector<char>> &board, int i, int j)
{//填入数字
if (board[i][j] != '.')
{
if (j == 8)
{
if (i == 8)
{
return;
}
else
{
++i;
j = 0;
}
}
else
{
++j;
}
dfs(board, i, j);
}
else
{
for (int m = 1; m < 10; ++m)
{//不要更改i,j的值,否则会出错。m代表尝试填入的数字
if (CanInput(board, i, j, m))
{
board[i][j] = (char)(m + '0');
if (j == 8)
{
if (i == 8)
{
return;
}
else
{
dfs(board, i + 1, 0);
}
}
else
{
dfs(board, i, j + 1);
}
int sign = 0; //进行判断数独是否已经符合条件
for (int q = 0; q < 9; ++q)
{
for (int e = 0; e < 9; ++e)
{
if (board[q][e] == '.')
{
sign = 1;
}
}
}
if (sign == 0)
{
return;
}
}
}
board[i][j] = '.'; //数字都填过还是不符合条件,就重置
}
}
bool CanInput(const vector<vector<char>>& board, int i, int j, int x)
{//判断是否可以填入
for (int m = 0; m < 9; ++m)
{
if (board[i][m] - '0' == x)
{
return false;
}
if (board[m][j] - '0' == x)
{
return false;
}
}
for (int m = i / 3 * 3 ; m < i / 3 * 3 + 3; ++m)
{
for (int n = j / 3 * 3 ; n < j / 3 * 3 + 3; ++n)
{
if (board[m][n] - '0' == x)
{
return false;
}
}
}
return true;
}
};