力扣刷题37.解数独

题目:

编写一个程序,通过填充空格来解决数独问题。

数独的解法需 遵循如下规则:

数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图)
数独部分空格内已填入了数字,空白格用 '.' 表示。

示例 1:


输入:board = [["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"]]
输出:[["5","3","4","6","7","8","9","1","2"],["6","7","2","1","9","5","3","4","8"],["1","9","8","3","4","2","5","6","7"],["8","5","9","7","6","1","4","2","3"],["4","2","6","8","5","3","7","9","1"],["7","1","3","9","2","4","8","5","6"],["9","6","1","5","3","7","2","8","4"],["2","8","7","4","1","9","6","3","5"],["3","4","5","2","8","6","1","7","9"]]

思路分析:

  第一步,创建一个列表board,表示输入的初始数独题目。对于同一行,列表中创建一个列表。对于一个元素位置,也相应创建一个列表,原因是后序的加入可能取值达到相同格式。

  第二步,筛选出可能元素,这里我分为3个循环,第一个循环同行,对于同行的元素加入到search2中。第二个循环同列,对于同列也是相同的处理方法。对于同一个方格的循环,先把空位置定位出他的方格,再转换循环他方格内部的元素,加入到search2中。这里注意,列表的特性是不允许出现相同的值,这里就得做一个小处理,判断此元素是否曾经出现在search2。循环完毕后,用search1(包含所有的可能取值)减去所有的search2得到search,再加入到原本的board中即可。

  第三步,用已生成的board查询新产生的只有一个单位长度的元素,再去排除同行同列同方格的元素,多次循环,即可得到最终答案。

代码:

import pandas as pd
import numpy as np
#coding='utf-8'


board = [[[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]]
        ]

def shuchu(board):
    for i in range(9):
        print()
        for j in range(9):
            print(board[i][j],end=' ')
    print()
shuchu(board) #查看输入是否正确
def chazhao(board):
    for i in range(9):
        for j in range(9):
            if len(board[i][j])!=1:
                search = []
                search1 = [1,2,3,4,5,6,7,8,9]
                search2 = []
                for a in range(9):#循环列
                    if a!=j:#不能等于同列
                        if len(board[i][a])==1:
                            search2.append(board[i][a][0])
                for b in range(9):#循环行
                    if b!=i:
                        if len(board[b][j])==1:
                            search2.append(board[b][j][0])
                I = int(i/3)*3
                J = int(j/3)*3
                for c in range(I,I+3):#循环同个单元格 不能有重复值
                    for d in range(J,J+3):
                        if c!=i & d!=j:
                            if len(board[c][d])==1:
                                if board[c][d] not in search2:
                                    search2.append(board[c][d][0])
                search = set(search1)-set(search2)
                search = list(search)
                board[i][j] = search
    return board
def main(board):
    for i in range(9):
        for j in range(9):
            if len(board[i][j])==0:
                board = chazhao(board)
    shuchu(board)

    for i in range(9):
        for j in range(9):
            board = chazhao(board)
    shuchu(board)

main(board)

 

题目分析:

  此题目有一个很大的漏洞,若在第三步循环时候,得到的值不是长度为1的,那么就得需要挨个尝试值,若不满足采用回溯算法得出结果,代码中没有体现此分析的代码。

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

想成为数据分析师的开发工程师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值