Loading

Leetcode - 37. 解数独

编写一个程序,通过填充空格来解决数独问题。
数独的解法需 遵循如下规则:

  1. 数字1-9在每一行只能出现一次。
  2. 数字1-9在每一列只能出现一次。
  3. 数字1-9在每一个以粗实线分隔的3x3宫内只能出现一次。(请参考示例图)

数独部分空格内已填入了数字,空白格用 '.' 表示。

示例:

输入: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.length == 9
  • board[i].length == 9
  • board[i][j] 是一位数字或者 '.'
  • 题目数据保证输入数独仅有一个解

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/sudoku-solver
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

(错误)解1 2021/9/2 O(?)

import numpy as np

def solveSudoku(board: list) -> None:
    """
    Do not return anything, modify board in-place instead.
    """
    # 9行,9列,9个单元
    # 情况有限,直接遍历
    # 1)行
    # np[0] ~ np[8]
    # 2)列
    # np[:,0] ~ np[:,8]
    # 3)单元
    # np[0:3,0:3]
    # np[0:3,3:6]
    # np[0:3,6:9]
    # np[3:6,0:3]
    # np[3:6,3:6]
    # np[3:6,6:9]
    # np[6:9,0:3]
    # np[6:9,3:6]
    # np[6:9,6:9]

    # 按人的解法解,先按最笨的方法,没有技巧
    # 每个小格子有[1-9]备选,
    # 每个小格子,相关联的有,1)它的所在行;2)它的所在列;3)它所在的单元格
    # 当备选只剩1个的时候,小格子数确定,同步删除上述3种影响的每个小格子中的该数
    # 用数字吧,好写
    g=np.zeros(shape=(9,9),dtype=list)
    for x in range(0,9):
        for y in range(0,9):
            if board[x][y]=='.': g[x][y]=[1,2,3,4,5,6,7,8,9]
            else: g[x][y]=[int(board[x][y])]
    # print(g)
    update=1
    while update:
        update=0
        for x in range(0,9):
            for y in range(0,9):
                # 找已经确定的小格子,然后更新它影响的行、列、单元
                # 对于g[x][y]来说,影响的是,
                # g[x], g[:,y], g[x//3:x//3+3,y//3:y//3+3]
                if g[x][y].__len__()==1:
                    value=g[x][y][0]
                    hang=g[x]
                    lie=g[:,y]
                    unit=g[(x//3)*3:(x//3)*3+3,(y//3)*3:(y//3)*3+3]
                    # hang
                    for i in hang:
                        if i.__len__()==1: continue
                        for idx,v in enumerate(i):
                            if v==value:
                                del i[idx]
                                update = 1
                                break
                    # lie
                    for i in lie:
                        if i.__len__()==1: continue
                        for idx,v in enumerate(i):
                            if v==value:
                                del i[idx]
                                update = 1
                                break
                    # unit
                    for i in range(0,3):
                        for j in range(0, 3):
                            if unit[i][j].__len__()==1: continue
                            for idx, v in enumerate(unit[i][j]):
                                if v == value:
                                    del unit[i][j][idx]
                                    update = 1
                                    break
    #print('=================================================')
    #print(g)
    for x in range(0,9):
        for y in range(0,9):
            board[x][y]=str(g[x][y][0])
    return

if __name__ == '__main__':
    '''
    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"]]
    solveSudoku(board)
    '''
    board =\
    [[".", ".", "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", ".", "."]]
    solveSudoku(board)

简单的处理,对于board2来说,只能得到以下结果,解不出最终的解:

感觉需要递归去做。

posted @ 2021-09-01 20:28  wwcg2235  阅读(33)  评论(0)    收藏  举报