您的位置:首页 > 编程语言 > Python开发

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%

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: