思路
这是第一个自己解出来的Hard。用N皇后的递归思路,扫每一个空格,遍历1-9看可以放哪个数字,如果都不能放就清理现场回到上一层递归继续遍历。后来参考别人的思路,模拟人解题,先找出每个位置可以填的候选数,按照可填候选数的数目排序,从最少的开始填,这样剪枝掉一些不必要的计算。
代码
class Solution:
def isValidPosition(self, n, row, col, board):
for i in range(9):
if board[row][i] == n:
return False
if board[i][col] == n:
return False
if board[3 * (row // 3) + i // 3][3 * (col // 3) + i % 3] == n:
return False
return True
def solveSudoku(self, board):
"""
:type board: List[List[str]]
:rtype: void Do not return anything, modify board in-place instead.
"""
blank = []
for i in range(9):
for j in range(9):
if board[i][j] == '.':
valid_digit = []
for n in [chr(x) for x in range(49, 58)]:
if self.isValidPosition(n, i, j, board):
valid_digit.append(n)
blank.append((i, j, valid_digit))
blank.sort(key=lambda x: len(x[2]))
self.flag = 0
def fill(pos, board):
if pos == len(blank):
self.flag = 1
return
for n in blank[pos][2]:
if len(blank[pos][2]) == 1:
board[blank[pos][0]][blank[pos][1]] = n
fill(pos + 1, board)
else:
if self.isValidPosition(n, blank[pos][0], blank[pos][1], board):
board[blank[pos][0]][blank[pos][1]] = n
fill(pos + 1, board)
if self.flag == 1:
break
board[blank[pos][0]][blank[pos][1]] = '.'
fill(0, board)