突然想起來最近刷的題,有一道題正好是「有效的數獨」,簡單思索一下,再加上一點回溯 + 剪枝,應該就可以程式上解決這個問題了,於是開啟剛關上的電腦,開始coding
思考的解題思路有兩種:
暴力遍歷所有的可能性,然後檢索是否是有效的數獨,如果是無效的,從後往前的修改填入的元素,知道遍歷完所有可能性或者找到有效解。但是這種方式效率感覺過低,不太想嘗試
回溯 + 剪枝,在填入數字前,先判斷在當前位置填入當前數字後,是否是有效的數獨,如果是無效的,則繼續判斷下個數字,依次類推
因為借用了之前的**, 所以這次寫** + 除錯**,用了大概10分鐘左右搞定了
感嘆一下,平時多刷刷演算法題,還是有好處的,思路開擴很多
#coding=utf-8
import time
import random
class solution:
def __init__(self, shudu_array):
# 要解的原始數獨
self.shudu_array = shudu_array
# 用於記錄當前每行、每列、每個小方格已填入的陣列,用於判斷是否是有效的數獨
self.rec = ,\
'column' : ,\
'rect' : }
# 根據原始數獨陣列,初始化記錄表
for row in range(0, 9):
for column in range(0, 9):
rect_num = row // 3 * 3 + column // 3
if shudu_array[row][column] == 0:
continue
curr_num = shudu_array[row][column]
# 判斷是否是有效的數獨
def is_valid(self, row, column, rect_num):
rect_num = row // 3 * 3 + column // 3
if self.shudu_array[row][column] == 0:
return false
curr_num = self.shudu_array[row][column]
if curr_num in self.rec['row'][row]:
return false
elif curr_num in self.rec['column'][column]:
return false
elif curr_num in self.rec['rect'][rect_num]:
return false
return true
# 主流程函式
def get_res(self):
row, column = self.get_zero_pos()
# 如果找不到需要填寫數字的位置,則已求得解,遞迴結束
if row >= 9 or column >= 9:
return true
# 小方格的編號
rect_num = row // 3 * 3 + column // 3
#for val in range(1, 10):
int_lst =
while true:
if 9 == len(int_lst):
return false
# 為了增加趣味性,使用隨機值代替
# 如果不想要隨機結果,放開50行的for迴圈,注釋掉51 - 60行的while迴圈
val = random.randint(1, 9)
if val in int_lst:
continue
self.shudu_array[row][column] = val
# 判斷填入數字後,是否是有效的數獨
if not self.is_valid(row, column, rect_num):
self.shudu_array[row][column] = 0
continue
# 更新記錄表的行、列和小方格資料
# 判斷是否填入成功
if self.get_res():
return true
self.shudu_array[row][column] = 0
self.rec['row'][row].pop()
self.rec['column'][column].pop()
self.rec['rect'][rect_num].pop()
return false
# 獲取下個需要填寫數字的行列下標
def get_zero_pos(self):
for row in range(0, 9):
for column in range(0, 9):
if 0 == self.shudu_array[row][column]:
return row, column
return row + 1, column + 1
if __name__ == '__main__':
shudu_array = [[9,0,0,0,0,0,0,0,0],
[0,0,2,6,0,0,0,0,0],
[0,8,0,0,3,0,5,0,0],
[0,1,0,0,0,8,0,0,0],
[0,0,0,0,4,1,8,0,0],
[0,0,0,0,0,0,0,2,0],
[0,0,0,0,0,0,0,6,9],
[0,0,9,1,0,0,0,0,0],
[0,3,0,0,0,0,4,0,0]]
start_time = time.time()
shudu = solution(shudu_array)
shudu.get_res()
if shudu.get_res():
for row in shudu_array:
print(row)
end_time = time.time()
print("duration : ", end_time - start_time)
回溯法數獨求解
public class sodutest 包含兩個解的,public static void main string args 核心演算法,利用遞迴回溯,求出所有解 param x 起始第 x 行 param y 起始第 y 列 return private boolean getsoduansw...
回溯法數獨求解
public class sodutest 包含兩個解的,public static void main string args 核心演算法,利用遞迴回溯,求出所有解 param x 起始第 x 行 param y 起始第 y 列 return private boolean getsoduansw...
數獨(Sudoku)求解程式
數獨完全求解程式 ver 3.0 coolypf 2008 11 24 22 11 include using namespace std int matrix 9 9 數獨矩陣 int count 0 解的個數 int check int x,int y,bool mark 10 檢測matrix...