【问题标题】:backtracking sudoku solver in python leetcode problempython leetcode问题中的回溯数独求解器
【发布时间】:2021-07-11 09:59:23
【问题描述】:

我正在计算正确的输出,但是当它返回到主调用函数时,我的数独板数组没有被修改,它正在打印原始板值。 我无法弄清楚它为什么会发生以及如何解决它。

class Solution:
def solveSudoku(self, board: List[List[str]]) -> None:
    
    if self.solve(board,0,0):#after this board is giving its old values not the modfied
        return board


def solve(self,board,row,col):
    if row == len(board):# here board is calculating correct output
        return True
    
    ni = 0
    nj = 0
    
    if (col == len(board[0]) -1):
        ni = row + 1
        nj = 0
    else:
        ni = row
        nj = col + 1
        
    if (board[row][col] != "."):
        self.solve(board,ni,nj)
    
    
    else:
        for p in range(1,10):
            if (self.isValid(board,row,col,p) == True):
                board[row][col] = str(p)
                self.solve(board,ni,nj)
                board[row][col] = "."


def isValid(self,board,x,y,p):
    for j in range(len(board[0])):
        if board[x][j] == str(p):
            return False
    
    for i in range(len(board[0])):
        if board[i][y] == str(p):
            return False
    
    si = (x//3)*3
    sj = (y//3)*3
    
    
    for i in range(3):
        for j in range(3):
            if board[si+i][sj+j] == str(p):
                return False
    return True

输入:
[["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",".",".","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"]]

leetcode 上的问题链接: https://leetcode.com/explore/learn/card/recursion-ii/472/backtracking/2796/

【问题讨论】:

    标签: python-3.6


    【解决方案1】:

    我认为这是问题所在:

        if (self.isValid(board,row,col,p) == True):
                board[row][col] = str(p)
                self.solve(board,ni,nj)
                board[row][col] = "."
    

    我不会深入研究您的整个算法,只会分析这一部分。如果有效,您正在设置板值:

        board[row][col] = str(p)
    

    然后调用这个函数:

           self.solve(board,ni,nj)
    

    这个函数最终只返回True。想象你一直在调用同一个函数,第一个值必须是有效的,但如果下一个值无效,那么你必须从“solve()”返回某个“False”。因此,如果任何值无效,则必须删除插入的内容,将“board[row][col]”恢复为原始值。

    因为solve()总是返回true,所有函数出栈后,这个board[row][col] = "."会被执行,所以你永远不会修改状态。 board[row][col] = "." 这必须在你返回 False 后执行

    【讨论】: