题意
解一个大小为 9*9 的数独。
思路
回溯法。
存储每一行、每一列、每个块分别有哪些数字已经使用过,每次填写新的数字之前都要检查,如果当前的数字是可行的,则递归地检查、填写下一个数字。递归函数的返回值可以用来判断是否有解,在第 i 行第 j 列时,如果已经找到了解,就直接返回,否则往当前位置填另外一个数字。
递归的结束条件是:位置越界。这表明已经填完了整个数独。
python代码
class Solution:
def __init__(self):
self.rowvis = []
self.colvis = []
self.blockvis = []
for i in range(0, 9):
self.rowvis.append([False] * 9)
self.colvis.append([False] * 9)
self.blockvis.append([False] * 9)
def solveSudoku(self, board):
"""
:type board: List[List[str]]
:rtype: void Do not return anything, modify board in-place instead.
"""
sx = -1
sy = -1
for i in range(0, 9):
for j in range(0, 9):
if board[i][j] != '.':
num = int(board[i][j]) - 1
self.rowvis[i][num] = True
self.colvis[j][num] = True
self.blockvis[self.getBlock(i, j)][num] = True
elif sx == -1:
sx = i
sy = j
self.dfs(board, sx, sy)
def getBlock(self, x, y):
return (x // 3) * 3 + y // 3
def dfs(self, board, x, y):
if x == 9:
return 1
r = x
c = y
while True:
c += 1
if c == 9:
r += 1
c = 0
if r == 9:
break
if board[r][c] == '.':
break
for i in range(0, 9):
if self.rowvis[x][i] or self.colvis[y][i] or self.blockvis[self.getBlock(x, y)][i]:
continue
board[x][y] = str(i + 1)
self.rowvis[x][i] = True
self.colvis[y][i] = True
self.blockvis[self.getBlock(x, y)][i] = True
if self.dfs(board, r, c):
return 1
board[x][y] = '.'
self.rowvis[x][i] = False
self.colvis[y][i] = False
self.blockvis[self.getBlock(x, y)][i] = False
return 0
C++代码
class Solution
{
public:
Solution() : n(9)
{
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
rowvis[i][j]=colvis[i][j]=blockvis[i][j]=false;
}
void solveSudoku(vector<vector<char>>& board)
{
int sx=-1,sy=-1;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
{
if(board[i][j]!='.')
{
board[i][j]-='1';
int num=board[i][j];
rowvis[i][num]=true;colvis[j][num]=true;
blockvis[getBlock(i,j)][num]=true;
}
else if(sx==-1)
sx=i,sy=j;
}
dfs(board,sx,sy);
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
board[i][j]+='1';
}
private:
int n;
array<array<bool,9>,9> rowvis;
array<array<bool,9>,9> colvis;
array<array<bool,9>,9> blockvis;
int getBlock(int x, int y) { return (x/3)*3+y/3; }
int dfs(vector<vector<char>>& board, int x, int y)
{
if(x==n)
return 1;
int r=x,c=y;
while(true)
{
c++;if(c>=n) r++,c=0;
if(r>=n) break;
if(board[r][c]=='.') break;
}
for(int i=0;i<n;i++)
{
if(rowvis[x][i] || colvis[y][i] || blockvis[getBlock(x,y)][i])
continue;
rowvis[x][i]=colvis[y][i]=blockvis[getBlock(x,y)][i]=true;
board[x][y]=i;
if(dfs(board,r,c))
return 1;
board[x][y]='.';
rowvis[x][i]=colvis[y][i]=blockvis[getBlock(x,y)][i]=false;
}
return 0;
}
};