leetcode 題目1162 解數獨

2021-10-23 01:52:49 字數 2166 閱讀 7817

2020/3/30  打卡

編寫乙個程式,通過已填充的空格來解決數獨問題。

乙個數獨的解法需遵循如下規則:

(1)數字 1-9 在每一行只能出現一次。

(2)數字 1-9 在每一列只能出現一次。

(3)數字 1-9 在每乙個以粗實線分隔的 3x3 宮內只能出現一次。

這裡每個3*3的宮都是 乙個塊。 這裡需要對所有的空位.標記位置進行填充

note:

給定的數獨序列只包含數字 1-9 和字元 '.' 。

你可以假設給定的數獨只有唯一解。

給定數獨永遠是 9x9 形式的

思路比較簡單,建立三個 可用數字統計列表,分別從 行、列、宮三個角度進行放納和刪除,並使用dfs+回溯+剪枝的方式進行逐步空位的填充。

時間複雜度為o(9!^9),空間複雜度為o(9^2)

# 思路比較簡單,建立三個 可用數字統計列表,分別從 行、列、宮三個角度進行放納和刪除,並使用dfs+回溯+剪枝的方式進行逐步空位的填充。

# 時間複雜度為o(9!^9),空間複雜度為o(9^2)

class solution(object):

def solvesudoku(self, board):

# 初始設定在每個位置可以使用的數字,預設的話,初始任何數字都是可以用的。

# 行 列 宮 剩餘可用數字

row=[set(range(1, 10)) for _ in range(9)]

col=[set(range(1, 10)) for _ in range(9)]

block=[set(range(1, 10)) for _ in range(9)]

############################ 空位和可用數收集 ########################

# 收集需填數字置 empty。 並根據現有分布情況 去除那些 在row 、col、block對應序號下按規則不可以用的數字。

empty =

for i in range(9):

for j in range(9):

# 更新可用數字 如果是數字的話,進行 行、列上的可用數字更新, 進行一些移除,標識不能用這幾個數字。

if board[i][j] != '.':

val = int(board[i][j])

row[i].remove(val)

col[j].remove(val)

# 對3*3宮 內數字進行移除,標識在當前 塊序號 內不能使用這個數

block[(i // 3)*3 + j // 3].remove(val)

else:

# 加入空位序號

############################ 對空閒位置,啟動回溯方式的填充嘗試 ########################

def backtrack(iter=0):

# 處理完empty代表找到了答案

if iter == len(empty):

return true

# 獲取當前需要填充的空位序號 、以及所歸屬的塊 。

i, j = empty[iter]

b = (i // 3)*3 + j // 3

# 獲取到行列 和 塊內共同認可的數字。 進行填充嘗試使用。 【但是這種填充不一定對,所以只是一種dfs演算法,如果不對就對填充操作回溯。】

for val in row[i] & col[j] & block[b]:

# 填充後的去除 可用數字操作

row[i].remove(val)

col[j].remove(val)

block[b].remove(val)

board[i][j] = str(val)

# 進行 下一步的 後乙個空位的dfs填充操作

if backtrack(iter+1):

return true

# 回溯操作,還原。

row[i].add(val)

col[j].add(val)

block[b].add(val)

# 這裡沒有明顯的剪枝,當在當前dfs下,無法 進行空位填充,不能執行for下的操作時,就自動進行樹的剪枝即可。

return false

backtrack()

leetcode經典題目 兩數相加(PHP解法)

給出兩個非空的鍊錶用來表示兩個非負的整數。其中,它們各自的位數是按照逆序的方式儲存的,並且它們的每個節點只能儲存一位數字。如果,我們將這兩個數相加起來,則會返回乙個新的鍊錶來表示它們的和。您可以假設除了數字 0 之外,這兩個數都不會以 0 開頭。示例 輸入 2 4 3 5 6 4 輸出 7 0 8 ...

ACM 演算法題目解

在乙個果園裡,多多已經將所有的果子打了下來,而且按果子的不同種類分成了不同的堆。多多決定把所有的果子合成一堆。每一次合併,多多可以把兩堆果子合併到一起,消耗的體力等於兩堆果子的重量之和。可以看出,所有的果子經過n 1次合併之後,就只剩下一堆了。多多在合併果子時總共消耗的體力等於每次合併所耗體力之和。...

PATB 解pat乙級題目

記 最近為了準備考研機試所以寫寫pat習題和ccf題目,為了給自己設定乙個進度條,我便想把自己每日做的題目貼上來。一是可以看看自己每天到底學了什麼 而來也分享自己的題解。如果有錯誤的地方,還請大家指出,非常謝謝!1085 pat單位排行 25分 每次 pat 考試結束後,考試中心都會發布乙個考生單位...