题意
解一个大小为 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; } };