37解数独
Posted xxswkl
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了37解数独相关的知识,希望对你有一定的参考价值。
题目: 编写一个程序,通过已填充的空格来解决数独问题。
来源: https://leetcode-cn.com/problems/sudoku-solver/
法一: 自己的代码
思路: 利用回溯法典型的模板,对没有填空的逐个遍历,测试用例的时候一定要注意边界条件,这个题的边界条件是九宫格的最后一个空,要分空和非空进行测试.回溯的时候有两种情况需要返回,一是全部填完了需要返回结果,二是某个格子没有可以填的数字,这时需要结束本次回溯,当用回溯法只返回一种情况的时候(如60题第K个排列),这时要把回溯函数写在return后面,当有两种及以上情况时,可以返回不同的值,用if语句进行判断,分别处理.
# 执行用时 :260 ms, 在所有 python3 提交中击败了34.63% 的用户 # 内存消耗 :12.8 MB, 在所有 python3 提交中击败了97.83%的用户 import typing as List class Solution: def solveSudoku(self, board): def cannot_place(row,col): # 如果为‘.‘,说明可以放置数字,返回False,如果到最后一个或超出边界了,说明所有的都填满了 if (board[row][col] == ‘.‘) or ([row,col] in [[8,8],[9,0]]): return False else: return True def move_to_next_number(row,col): # 注意这里边界条件的设定,非常重要,很容易错 if col<8: return row,col+1 # 只有到了每行的最后一列,才会执行这个判断, elif row<8: col = 0 return row+1,col else: return 8,8 # 求(row,col)处可以填的数字 def diff_set(row,col): # a记录位置(row,col)所在行和列的数字 a = board[row] + [board[i][col] for i in range(9)] # k记录位置(row,col)所在九宫格的数字 p = int(row / 3) q = int(col / 3) dict = {0: (0, 3), 1: (3, 6), 2: (6, 9)} m, n = dict[p] u, v = dict[q] a = sum([i[u:v] for i in board[m:n]], []) + a a = set(a) if ‘.‘ in a: set(a).remove(‘.‘) b = [str(i+1) for i in range(9)] return list(set(b) - set(a)) def backtrack(row,col): # 如果当前位置有数字,则移到下一个 while cannot_place(row,col): row,col = move_to_next_number(row,col) # 如果到最后一个格子了,且该格不为空,则结束 if (row==8) & (col==8) & (board[8][8] != ‘.‘): return True # 利用三个限定条件,减少数字的遍历数目 nums = diff_set(row,col) # 如果这个格子没有数字可以填了,则返回False回溯 if len(nums) == 0: return False for i in nums: board[row][col] = i # 这里为了避免重复判断,提前将空格移动到下一个,当前空格已经有数字了, # 无需在下一次的回溯中用while判断了,由于这里没有用while,要放止越界 p,q = move_to_next_number(row,col) # 这里的写法非常巧妙,因为回溯函数有两种情况需要中断,所以用一个if条件来判断 # 如果遇到nums为0,无法继续回溯,则返回False进行下一个, # 如果是找到合适的了,则返回True,结束程序 if backtrack(p,q): return True board[row][col] = ‘.‘ backtrack(row=0,col=0) if __name__ == ‘__main__‘: # data=[["5","3",".",".","7",".",".",".","."], # ["6",".",".","1","9","5",".",".","."], # [".","9","8",".",".",".",".","6","."], # ["8",".",".",".","6",".",".",".","3"], # ["4",".",".","8",".","3",".",".","1"], # ["7",".",".",".","2",".",".",".","6"], # [".","6",".",".",".",".","2","8","."], # [".",".",".","4","1","9",".",".","5"], # [".",".",".",".","8",".",".","7","9"]] data = [[".",".","9","7","4","8",".",".","."], ["7",".",".",".",".",".",".",".","."], [".","2",".","1",".","9",".",".","."], [".",".","7",".",".",".","2","4","."], [".","6","4",".","1",".","5","9","."], [".","9","8",".",".",".","3",".","."], [".",".",".","8",".","3",".","2","."], [".",".",".",".",".",".",".",".","6"], [".",".",".","2","7","5","9",".","."]] duixiang = Solution() duixiang.solveSudoku(data) print(data)
法二: 官方代码
思路:
以上是关于37解数独的主要内容,如果未能解决你的问题,请参考以下文章