這是 leetcode #37(數獨求解器)。
我有一個關于在遞回函式中就地修改輸入串列的問題。下面的代碼幾乎可以完成這項作業,因為它print(board)確實列印了正確的解決方案(我確信效率可以提高,但這不是這個問題的重點,哈哈)。但是,我無法保存修改后的board(或其副本) -board最后列印總是給出原始輸入。
我知道我可以在回溯函式中創建另一個路徑變數來記錄所有填充的數字,但它似乎有點太笨拙了......有沒有一種有效的方法可以在解決方案完成時保存修改后的輸入串列?非常感謝!
class Solution:
def solveSudoku(self, board):
def options(board, i, j):
numbers = ['1', '2', '3', '4', '5', '6', '7', '8', '9']
choices = numbers.copy()
for col in range(9):
if board[i][col] in choices:
choices.remove(board[i][col])
for row in range(9):
if board[row][j] in choices:
choices.remove(board[row][j])
corner_x, corner_y = (i // 3) * 3, (j // 3) * 3
for row in range(corner_x, corner_x 3):
for col in range(corner_y, corner_y 3):
if board[row][col] in choices:
choices.remove(board[row][col])
return choices
def back_tracking(board, pos):
if pos <= 81:
if pos == 81:
print(board)
return
else:
i, j = divmod(pos, 9)
if board[i][j] != '.':
back_tracking(board, pos 1)
elif options(board, i, j) != []:
for choice in options(board, i, j):
board[i][j] = choice
back_tracking(board, pos 1)
board[i][j] = '.'
back_tracking(board, 0)
return board
uj5u.com熱心網友回復:
問題在這里:
for choice in options(board, i, j):
board[i][j] = choice
back_tracking(board, pos 1) # <<< here
board[i][j] = '.'
在您的實作中,即使back_tracking標記行中的呼叫實際上解決了難題,代碼也會繼續執行下一行。將數字恢復為'.',并繼續下一個選擇,忽略已經找到解決方案的事實。最終,它會嘗試所有內容并將所有內容還原,因此棋盤與原始棋盤相同。
換句話說:您的代碼已經在更改適當的值,但是在嘗試了所有內容后,它正在將其全部更改回原始值。
我建議你做的是:一旦你得到一個有效的解決方案,就中斷遞回并停止。一種選擇是從您的遞回back_tracking函式中獲得一個實際的回傳值,如果找到解決方案,則回傳板本身,否則回傳 None,因此演算法繼續迭代。
def back_tracking(board, pos):
if pos == 81:
return board
i, j = divmod(pos, 9)
if board[i][j] != '.':
return back_tracking(board, pos 1)
if options(board, i, j) != []:
for choice in options(board, i, j):
board[i][j] = choice
if back_tracking(board, pos 1):
return board
board[i][j] = '.'
uj5u.com熱心網友回復:
您可以只索引值,也就是更新它的作業方式是這樣的。
board =[0,1,2]
board[0]=1
print(board)
輸出:
[1,1,2]
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/515663.html
