Sudoku Solver
要点:
- 和8 queen类似,dfs,同时要maintain row,column,box表示每个点所在的row,column和box的当前状态。本质是set,但是因为值是固定的,所以boolean array就可以,每个slot对应一个value
- 因为递归过程中要reset board value和row, column, box,会不会把board预留值也reset了?不会,因为是按顺序递归的,只要在递归前set/reset,所有初始值的格子都被skip了。
错误点
- 因为board上已经有值了,别忘了初始化row,column,box
- 解就是board本身,所以要同时更新board和row,column,box
- python integer和char的conversion: ord(‘9’)得到这个char的ascii,str(9) => ‘9’:注意python没有char的概念,所以str()就可以
- 函数内外的变量用同样的名字:i,j或者x,y,不一致很容易搞混
- box的坐标如何算:i/33+j/3: i/3得到row方向的box序数,再3表示之前几行有几个box,最后j/3得到同一行3个box的偏移量,曾经错误的用i*3/3+j/3
- 因为值和index是差1的,所以在loop里一定要用index,只有在赋值的时候+1,这样避免错误
class Solution(object):
def solveSudoku(self, board):
"""
:type board: List[List[str]]
:rtype: void Do not return anything, modify board in-place instead.
"""
def dfs(board, cur):
if cur>=81: return True
i, j = cur/9, cur%9
if board[i][j]=='.':
for bv in range(9):
if not row[bv][i] and not column[bv][j] and not box[bv][i/3*3+j/3]:
row[bv][i]=column[bv][j]=box[bv][i/3*3+j/3]=True
board[i][j]=str(bv+1)
if dfs(board, cur+1): return True
row[bv][i]=column[bv][j]=box[bv][i/3*3+j/3]=False
board[i][j]='.'
else:
return dfs(board, cur+1)
row = [[False for j in range(9)] for i in range(9)]
column = [[False for j in range(9)] for i in range(9)]
box = [[False for j in range(9)] for i in range(9)]
for i in range(9):
for j in range(9):
if board[i][j]!='.':
bv = ord(board[i][j])-ord('1')
row[bv][i]=column[bv][j]=box[bv][i/3*3+j/3]=True
dfs(board, 0)