Leetcode做题日记:37. 解数独(PYTHON)
2019-01-01 19:24
309 查看
编写一个程序,通过已填充的空格来解决数独问题。
一个数独的解法需遵循如下规则:
数字 1-9 在每一行只能出现一次。 数字 1-9 在每一列只能出现一次。 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。
空白格用 ‘.’ 表示。
Note:
给定的数独序列只包含数字 1-9 和字符 '.' 。 你可以假设给定的数独只有唯一解。 给定数独永远是 9x9 形式的。
第一次的代码:
首先设置一个函数,判断数字i是否可以插入,然后设置递归函数,在’ . '处插入数字,当9x9表格被填满后,返回表格x
A=['1','2','3','4','5','6','7','8','9'] def buchongtu(x,s,sx,sy): for i in range(9): if x[sy][i]==s: #判断行 return False if x[i][sx]==s: #判断列 return False a=3*(sx//3+1) b=3*(sy//3+1) for i in range(a-3,a): #判断所属3x3表格 for j in range(b-3,b): if x[j][i]==s: return False return True #可行返回True def jsd(X,s,sx,sy): x=X[:] #避免直接修改表格,选择使用切片 x[sy][sx]=s #将s填入表格 while x[sy][sx] in A: #当此格是数字时,不可填 sx+=1 #遍历到不是数组的格子 if sx==9: #遍历到行尾 sy=sy+1 sx=0 if sy==9: #遍历完表格,返回答案 return x for i in A: #从1-9填写此空格 if buchongtu(x,i,sx,sy): #如果数字可行 jsd(x,i,sx,sy) #迭代 return jsd(board,board[0][0],0,0)
但是没解出来,有可能是在递归过程中,每一个数独解都是从1-9遍历,有一个解猜错误之后,会不断返回一个NONE,导致程序提前结束
第二次代码:
修改了jsd函数,却忘记修好buchongtu函数,导数我一直没有得到答案,因为在jsd函数中已经对x[sy][sx]赋值,如果不修改,buchongtu函数会一直返回False。在jsd函数中,在添加数字的同时判断是否是正确数字,因为只有一个解,在递归过程中,已经把数字全部填写好了。
A=['1','2','3','4','5','6','7','8','9'] def buchongtu(x,s,sx,sy): for i in range(9): if x[sy][i]==s and i!=sx: #防止选择sx列 return False if x[i][sx]==s and i!=sy: #防止选择sy行 return False a=3*(sx//3+1) b=3*(sy//3+1) for i in range(a-3,a): #判断3x3表格 for j in range(b-3,b): if x[j][i]==s and j!=sy and i!=sx: return False #防止选择[sy][sx]坑 return True def jsd(x): for i in range(9): for j in range(9): if x[i][j]=='.': #对空操作 for k in A: x[i][j]=k #填写k if buchongtu(x,k,j,i) and jsd(x): return True #如果正确,返回True x[i][j]='.' #如果k不正确,则先不填写,等重填 return False #如果没有返回True,表明没有数字可填 #第一个数字就填错了,则返回False,阻止 #第一个数字的填写,只有全部正确才能填 return True #当两个for不返回值时,表明已经遍历结束,刚才填写正确 jsd(board)
908ms,排名50%
如果jsd()不采用两个for循环,可采用while:
作用是一样的遍历整个列表的空
def jsd(x,index): while index <81:#有点巧妙,计算行i,列j i=index/9 j=index%9 if x[i][j]=='.': for k in A: x[i][j]=k if buchongtu(x,k,j,i) and jsd(x,index): return True x[i][j]='.' return False index+=1 return True jsd(board,0)
676ms,排名57%
当然也可以while结束后再for循环:
def jsd(x,index): while index <81: i=index/9 j=index%9 if x[i][j]=='.': break #反正都是每次递归都会填写一个数 index+=1 #所以每次调用只需要找一个空就行了 if index<81:#如果没满 for k in A: x[i][j]=k if buchongtu(x,k,j,i) and jsd(x,index+1):#这里+1可去 return True #确保填写的是正确的 x[i][j]='.' return False #如无法填写,返回重填 else: #如果满了 return True jsd(board,0)
608ms,排名58%
相关文章推荐
- Leetcode做题日记:49. 字母异位词分组(PYTHON)
- Leetcode做题日记:51. N皇后(PYTHON)
- Leetcode做题日记:55. 跳跃游戏(PYTHON)
- Leetcode做题日记:58. 最后一个单词的长度(PYTHON)
- Leetcode做题日记:41. 缺失的第一个正数(PYTHON)
- Leetcode做题日记:52. N皇后 II(PYTHON)
- Leetcode做题日记:45. 跳跃游戏 II(PYTHON)
- Leetcode做题日记:43. 字符串相乘(PYTHON)
- Leetcode做题日记:38. 报数(PYTHON)
- Leetcode做题日记:39. 组合总和(PYTHON)
- Leetcode做题日记:46. 全排列(PYTHON)
- Leetcode做题日记:54. 螺旋矩阵(PYTHON)
- Leetcode做题日记:44. 通配符匹配(PYTHON)
- Leetcode做题日记:47. 全排列 II(PYTHON)
- Leetcode做题日记:59. 螺旋矩阵 II(PYTHON)
- Python 刷题日记:LeetCode 624. Maximum Distance in Arrays
- Python 刷题日记:LeetCode: 1&15&16-Two Sum and 3Sum
- Python 刷题日记:LeetCode 204: Count Primes
- python leetcode 637. Average of Levels in Binary Tree
- python leetcode 515. Find Largest Value in Each Tree Row