一、回溯算法概述
回溯算法是一种通过穷举来解决问题的方法,它的核心是从一个初始状态出发,暴力搜索所有可能的解决方案,记录正确的解,知道找到解或者尝试了所有可能都找不到解为止。
常见的回溯算法有"深度优先搜索",遍历整个空间,找到所有可能的节点,直到找到目标节点为止。
def pre_order(root):
# 退出条件
if root is None:
return
# 找到目标值后记录
if root.val == '目标值':
res.append(root)
# 搜索全部可能的解决方案
pre_order(root.left)
pre_order(root.right)
回溯算法最重要的就是恢复本次尝试之前的状态,我们可以用列表的append和pop来实现将状态尝试和回退,只需要在上述代码加上两行代码即可。
def pre_order(root):
# 退出条件
if root is None:
return
# 尝试
path.append(root)
# 找到目标值后记录
if root.val == '目标值':
res.append(root)
# 搜索全部可能的解决方案
pre_order(root.left)
pre_order(root.right)
# 回退
path.pop()
不过在很多问题上可能会有不止一个限制条件,而回溯本质上是对全局进行一个遍历,如果本身都不符合条件,则没有继续遍历的必要,节省大量的资源。
def pre_order(root):
# 退出条件
if root is None or root.val == '条件':
return
# 尝试
path.append(root)
# 找到目标值后记录
if root.val == '目标值':
res.append(root)
# 搜索全部可能的解决方案
pre_order(root.left)
pre_order(root.right)
# 回退
path.pop()
二、全排列问题
1、不包含重复元素
力扣第46题:https://leetcode.cn/problems/permutations/description/
给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。
此类问题就是需要我们去获得全部的结果,通过不断的尝试和回退去获取所有可能的结果。本题因为是指定列表要构成的所有情况,所以最后生成的结果中,没有重复的元素,保证顺序不同,只需要递归给定数组长度次就可以得到所有的情况。
class Solution:
def permute(self, nums: list[int]) -> list[list[int]]:
# 获得给定列表长度
lenth = len(nums)
# 定义结果变量
res = []
# 定义回溯函数
def get_back(count = 0):
# 设定条件,如果递归次数达到给定数组长度次就将得到的结果记录下来
if count == lenth:
res.append(nums[:])
return
# 遍历所有元素
for i in range(count, lenth):
# 维护数组
nums[count], nums[i] = nums[i], nums[count]
# 增加迭代次数再次迭代
get_back(count

最低0.47元/天 解锁文章
3260

被折叠的 条评论
为什么被折叠?



