回溯算法
[回溯算法(第07~09天)](04.03.01 回溯算法(第 07 ~ 09 天) (datawhalechina.github.io))
简介
“走不通就回退”思想
回溯算法三步走
1.明确所有选择
2.明确终止条件
3.将决策树和终止条件翻译成代码
练习
子集问题
1.数组中的每个位置上的元素都有两种选择:选与不选。
2.当遍历到决策树的叶子节点,满足终止条件。
3.引入两个全局变量res(存放所有符合条件结果的集合数组)path(存放当前符合条件的结果呢)
def subsets(nums):
res = []
path = []
def backtracking(nums,index):
res.append(path[:])
if index >= len(nums): #终止条件
return
for i in range(index,len(nums)):#枚举可选元素列表
path.append(nums[i]) #选择元素
backtracking(nums,i+1) #递归搜索
path.pop() #撤销选择
backtracking(nums,0)
return res
N皇后问题
n × n n{\times}n n×n的棋盘,对于每一行均有 n n n种选择,但是要检查冲突,即每一个皇后的行、列、对角线不能有其他皇后。因此,对于冲突的选择进行剪枝。
#N皇后
res = []
def backtrack( n: int, row: int, chessboard: List[List[str]]): #chessboard,棋盘数组,row,第row皇后
if row == n:
temp_res = []
for temp in chessboard:
temp_str = ''.join(temp)
temp_res.append(temp_str)
res.append(temp_res)
return
for col in range(n): #枚举可防止皇后的列
if isValid(n, row, col, chessboard): #与之前皇后的位置不冲突
chessboard[row][col] = 'Q' #选择row.col位置的皇后
backtrack(n, row + 1, chessboard) #递归放置row+1行之后的皇后
chessboard[row][col] = '.' #撤销选择row.col的位置
def isValid(n: int, row: int, col: int, chessboard): #判断是否与之前的皇后有冲突
for i in range(row):
if chessboard[i][col] == 'Q':
return False
i, j = row - 1, col - 1
while i >= 0 and j >= 0:
if chessboard[i][j] == 'Q':
return False
i -= 1
j -= 1
i, j = row - 1, col + 1
while i >= 0 and j < n:
if chessboard[i][j] == 'Q':
return False
i -= 1
j += 1
return True
def solveNQueens(n: int):
res.clear()
chessboard = [['.' for _ in range(n)] for _ in range(n)]
backtrack(n, 0, chessboard)
return res