题目描述
解题思路
暴力递归
使用dfs进行暴力递归,需要判断一下三个条件,标记一下是否出现过,行、列以及3*3的小格子中是否出现过。
注意递归结束的条件,失败后不要返回(在这里写错了,没注意到)。
代码实现
int r[12][12];
int c[12][12];
int g[12][12];
int mp[12][12];
class Solution
{
public:
int Change(int x)
{
if(x <= 3) return 1;
if(x <= 6) return 2;
return 3;
}
int dfs(int x, int y)
{
if(x == 10)
return 1;
int flag = 0;
if(mp[x][y] != 0)
{
if(y == 9)
flag = dfs(x+1, 1);
else
flag = dfs(x, y+1);
return flag;
}
else
{
int sx = Change(x);
int sy = Change(y);
if(sx == 2) sy += 3;
if(sx == 3) sy += 6;
flag = 0;
for(int i = 1; i <= 9; i++)
{
if(!r[x][i] && !c[y][i] && !g[sy][i])
{
mp[x][y] = i;
r[x][i] = 1;
c[y][i] = 1;
g[sy][i] = 1;
if(y == 9) flag = dfs(x+1, 1);
else flag = dfs(x, y+1);
if(!flag)
{
mp[x][y] = 0;
r[x][i] = 0;
c[y][i] = 0;
g[sy][i] = 0;
}
else
return flag;
}
}
}
return 0;
}
void solveSudoku(vector<vector<char>>& board)
{
memset(r, 0, sizeof(r));
memset(c, 0, sizeof(c));
memset(g, 0, sizeof(g));
for(int i = 0; i < 9; ++i)
{
for(int j = 0; j < 9; ++j)
{
if(board[i][j] == '.')
mp[i+1][j+1] = 0;
else
mp[i+1][j+1] = board[i][j]-'0';
if(mp[i+1][j+1] == 0) continue;
int num = mp[i+1][j+1];
r[i+1][num] = 1;
c[j+1][num] = 1;
int x = Change(i+1);
int y = Change(j+1);
if(x == 2) y += 3;
if(x == 3) y += 6;
g[y][num] = 1;
}
}
dfs(1,1);
for(int i = 1; i <= 9; ++i)
{
for(int j = 1; j <= 9; ++j)
board[i-1][j-1] = char(mp[i][j]+'0');
}
}
};
//测试样例
530070000
600195000
098000060
800060003
400803001
700020006
060000280
000419005
000080079