边工作边刷题:70天一遍leetcode: day 34

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)
            
原文地址:https://www.cnblogs.com/absolute/p/5678191.html