leetcode-37-解数独

题目描述:

 

 

 

自己提交:未找出错(留坑)

class Solution:
    def solveSudoku(self, board: List[List[str]]) -> None:
        def helper(i,j):
            if i==j==8:
                return True
            if i==8:
                print(i,j)
            if board[i][j].isdigit():
                if j+1==9 :
                    return helper(i+1,0)
                return helper(i,j+1)
            #block = (i+1)//3+((j+1)//3-1)*3
            nums = ["1","2","3","4","5","6","7","8","9"]
            nums2 = set()
            for x in range(9):
                if board[i][x]==".":continue
                nums2.add(board[i][x])
                if board[x][j]==".":continue
                if board[x][j] in nums2:return False
                nums2.add(board[x][j])
            for x in range(i//3*3 , i//3*3+3):
                for y in range(j//3*3, j//3*3+3):
                    if board[x][y]==".":continue
                    nums2.add(board[x][y])
            if len(nums2)==9:return False
            for num in nums :
                if num not in nums2:
                    board[i][j] = num
                    if j+1==9 :
                        if not helper(i+1,0):
                            board[i][j] = "."
                        else:
                            break
                    else:
                        if not helper(i,j+1):
                            board[i][j] = "."
                        else:
                            break
        helper(0,0)
        print(board)

方法:回溯

class Solution:
    def solveSudoku(self, board: List[List[str]]) -> None:
        """
        Do not return anything, modify board in-place instead.
        """
        # 把所有没填数字的位置找到
        all_points = []
        for i in range(9):
            for j in range(9):
                if board[i][j] == ".":
                    all_points.append([i, j])
        # check函数是为了检查是否在point位置k是合适的
        def check(point, k):
            row_i = point[0]
            col_j = point[1]
            for i in  range(9):
                # 检查 行
                if i != row_i and board[i][col_j] == k:
                    return False
                # 检查 列
                if i != col_j and board[row_i][i] == k:
                    return False
            # 检查块
            for i in range(row_i//3*3 , row_i//3*3+3):
                for j in range(col_j//3*3, col_j//3*3+3):
                    if i != row_i and j != col_j and board[i][j] == k:
                        return False
            
            return True
        
        def backtrack(i):
            # 回溯终止条件
            if i == len(all_points):
                return True
            for j in range(1, 10):
                # 检查是否合适
                if check(all_points[i],str(j)):
                    # 合适就把位置改过来
                    board[all_points[i][0]][all_points[i][1]] = str(j)
                    if backtrack(i+1): # 回溯下一个点
                        return True
                    board[all_points[i][0]][all_points[i][1]] = "."# 不成功把原来改回来
            return False
        
        backtrack(0)

 

posted @ 2019-10-18 09:21  oldby  阅读(396)  评论(0编辑  收藏  举报