Leetcode——37.解数独 [##]
@author: ZZQ
@software: PyCharm
@file: leetcode37_solveSudoku.py
@time: 2018/11/20 16:41
思路:递归回溯
首先,设置空矩阵bool_col,bool_row和bool_rect分别用于记录每一行,每一列,每个小方块里面已经被填进去的数字
然后,用回溯填空,如果填写的数组满足要求,则返回True,否则返回False. 直至便利完整个数组board。
import numpy
class Solution():
def __init__(self):
pass
def solveSudoku(self, board):
"""
:type board: List[List[str]]
:rtype: void Do not return anything, modify board in-place instead.
"""
# 记录每一行,每一列,每个小方块里面已经被填进去的数字
bool_col = numpy.zeros(shape=(9, 9)) # [[0] * 9] * 9
bool_row = numpy.zeros(shape=(9, 9))
bool_rect = numpy.zeros(shape=(9, 9))
for i in range(9):
for j in range(9):
if board[i][j] != '.':
bool_col[i][ord(board[i][j])-ord('0')-1] = 1
bool_row[j][ord(board[i][j])-ord('0')-1] = 1
bool_rect[i/3*3+j/3][ord(board[i][j])-ord('0')-1] = 1
self.dfs(board, bool_col, bool_row, bool_rect, 0, 0)
return board
# 回溯
def dfs(self, board, bool_col, bool_row, bool_rect, i, j):
while board[i][j] != '.': # 找空位置
j += 1
if j >= 9:
i += 1
j = 0
if i >= 9:
return True
for number in range(1, 10):
if bool_col[i][number-1] != 1 and bool_row[j][number-1] != 1 and bool_rect[i/3*3+j/3][number-1] != 1:
board[i][j] = str(number)
bool_col[i][number-1] = 1
bool_row[j][number-1] = 1
bool_rect[i / 3 * 3 + j / 3][number-1] = 1
if self.dfs(board, bool_col, bool_row, bool_rect, i, j):
return True
else: # 回溯,当前值不行,继续换下一个值进行尝试
board[i][j] = '.'
bool_col[i][number-1] = 0
bool_row[j][number-1] = 0
bool_rect[i / 3 * 3 + j / 3][number-1] = 0
return False
if __name__ == "__main__":
answer = Solution()
for i in answer.solveSudoku([
["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"]
]):
print(i)
CV小蜡肉