回溯算法(LeetCode基础)

回溯算法

[回溯算法(第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
  • 11
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Sean7566

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值