Leetcode - 51
首先这道题不同于以往的是,这是处理一个二维序列,前面我们都处理的是一维的,那么二维序列的话我们就要用两个for吗?其实这里不用,因为在每一行里,我们只要找到一个适合的位置放入皇后就可以直接continue到下一行了,所以说这里for循环只要一个,且这个for循环对应的是列数,行数我们用row来记录,在某一行找到合适位置后,就row+1传递都下一个递归当中。
关于终止条件,这里是row到最后一行n-1并完成处理后,也就是递归传递到下一层,此时row==n,这就是终止条件,此时我们收集结果。
关于位置是否合适,我们通过当前位置的同列上方元素,左上方对角线上元素,右上方对角线上元素来判断是否有皇后,没有皇后就表示位置合理。
def solveNQueens(self, n: int) -> List[List[str]]:
source = [["." for _ in range(n)] for _ in range(n)]
res = []
def process(board,row, col):
#判断同一列是否冲突
for i in range(len(board)):
if board[i][col] == 'Q':
return False
# 判断左上角是否冲突
i = row -1
j = col -1
while i>=0 and j>=0:
if board[i][j] == 'Q':
return False
i -= 1
j -= 1
# 判断右上角是否冲突
i = row - 1
j = col + 1
while i>=0 and j < len(board):
if board[i][j] == 'Q':
return False
i -= 1
j += 1
return True
def backTraking(raw,temp):
nonlocal res
if raw == n:
t = []
for line in temp:
t.append("".join(line))
res.append(t[:])
return
for i in range(n):
if not process(temp,raw,i):
continue
temp[raw][i] = "Q"
backTraking(raw +1,temp)
temp[raw][i] = "."
backTraking(0,source)
return res
Leetcode - 37
这题比N皇后还要难,这里是一行要可能填充多个元素,也是一个二维数据,所以这里我们并不能像N皇后那里使用row来避免两重循环了,这里外层循环代表行,内层循环代表列,注意此题只需要我们找到一个答案并填充即可,所以这里我们并不需要写终止条件,此处我们是仅需要在单个树枝上收集结果而不是像前面的回溯题一样在所有树枝上收集,这里是需要返回值的,通过返回值来标识什么时候可以终止递归
在棋盘中,一旦我们遇到值为“.”的元素,我们就开始从1~9中一一试值,这里判断值是否可以放入,我们需要单独写一个函数,三个点:1。 不能与同行元素重复 2. 不能与同列元素重复, 3. 不能在所处的3 * 3方阵中元素重复。不符合就continue,直到符合。符合 就赋值,然后进入下一次递归,递归有返回值,若为True则直接return 递归后依旧是将元素从数值还原成"."。
若在1-9中找不到元素,则返回False。
两次for循环结束后返回True,代表如果中间一直顺畅,每个位置都有合适的值放入,则完成
def solveSudoku(self, board: List[List[str]]) -> None:
"""
Do not return anything, modify board in-place instead.
"""
def getCurrPos(raw,col):
aSet = set()
if raw <=2:
a = board[:3]
elif raw > 2 and raw <=5:
a = board[3:6]
else:
a = board[6:]
if col <=2:
a = [line[:3] for line in a]
elif col >2 and col <=5:
a = [line[3:6] for line in a]
else:
a = [line[6:] for line in a]
for line in a:
for item in line:
aSet.add(item)
return aSet
def isValid(value,raw,col):
zong = [board[r][col] for r in range(9)]
if (value in board[raw]) or (value in zong) or (value in getCurrPos(raw,col)):
return False
return True
def backTracking():
nonlocal board
for i in range(9):
for j in range(9):
if board[i][j] == ".":
for v in range(1,10):
if not isValid(str(v),i,j):
continue
else:
board[i][j] = str(v)
if backTracking():
return True
board[i][j] = "."
else:
return False
return True
backTracking()
return board