代码随想录学习Day 21

回溯算法理论基础

回溯法又叫回溯搜索法。回溯是递归的副产品,有递归就会有回溯,回溯操作一般出现在递归函数的下面。回溯函数 == 递归函数。回溯法的本质是穷举。

回溯法解决的问题:

  • 组合问题:N个数里面按一定规则找出k个数的集合
  • 切割问题:一个字符串按一定规则有几种切割方式
  • 子集问题:一个N个数的集合里有多少符合条件的子集
  • 排列问题:N个数按一定规则全排列,有几种排列方式
  • 棋盘问题:N皇后,解数独等

回溯法解决的问题都可以抽象为树形结构,因为回溯法解决的都是在集合中递归查找子集,集合的大小就构成了树的宽度,递归的深度构成了树的深度

回溯法模板

回溯三部曲:

1.回溯函数参数及返回值:回溯函数命名一般为backtracking,函数返回值一般为void。对于参数,因为回溯算法需要的参数不容易确定,所以一般先写逻辑,然后需要什么参数就填什么参数。

def backtracking(参数) -> void:

2.回溯函数终止条件:回溯问题一般是树形结构,一般来说搜到叶子节点,也就找到了满足条件的一条答案,把这个答案存放起来,并结束本层递归。

if 终止条件:存放结果return

3.回溯函数遍历过程:回溯法一般是在集合中递归搜索,集合的大小构成了树的宽度,递归的深度构成的树的深度。过程如图:

for 选择:本层集合中元素(树中节点孩子的数量就是集合的大小):处理节点backtracking(路径,选择列表)  # 递归回溯,撤销处理结果

for循环就是遍历集合区间,可以理解一个节点有多少个孩子,这个for循环就执行多少次。backtracking这里自己调用自己,实现递归。从图中看出for循环可以理解是横向遍历,backtracking(递归)就是纵向遍历,这样就把这棵树全遍历完了,一般来说,搜索叶子节点就是找的其中一个结果了。

回溯算法模板框架如下:

def backtracking(参数):if 终止条件:存放结果returnfor 选择:本层集合中元素(树中节点孩子的数量就是集合的大小)处理节点backtracking(路径,选择列表); // 递归回溯,撤销处理结果

77.组合

题目链接

讲解链接

本题如果使用暴力解法,则需要嵌套k层for循环,当k值较大时完全无法实现,所以需要使用回溯法来解决。本题可以抽象为以下树形结构:

每次从集合中选取元素,可选择的范围随着选择的进行而收缩,调整可选择的范围图中可以发现n相当于树的宽度,k相当于树的深度图中每次搜索到了叶子节点,我们就找到了一个结果。相当于只需要把达到叶子节点的结果收集起来,就可以求得 n个数中k个数的组合集合。

回溯三部曲:

1.递归函数参数及返回值:参数一定要有n,k,以及一个startIndex,这个参数用来记录本层递归的中,集合从哪里开始遍历(集合就是[1,...,n] )。除此之外还需要两个全局变量result和path,前者用来保存符合条件的结果的集合,后者则用来保存符合条件的单一结果。

def __init__(self):self.path = []self.result = []
def backtracking(n, k, start_index):

2.递归终止条件:path这个数组的大小如果达到k,就说明找到了一个子集大小为k的组合,在树中path存的就是根节点到叶子节点的路径。这时候将path中的结果传入result中。

if len(path) == k:result.append(paht[:])return

3.单层递归逻辑:for循环从startindex开始遍历,用path保存取到的元素i,backtracking递归调用自己向深处遍历,遇到叶子节点则返回。

for i in range(startindex, n + 1):path.append(i)backtracking(n, k, i + 1)path.pop()

整体代码如下:

class Solution:def __init__(self):self.path = []  # 保存符合条件的单一结果self.result = []  # 保存符合条件的结果集合def backtracking(self, n, k, start_index):  # 回溯函数if len(self.path) == k:  # 终止条件self.result.append(self.path[:])  # 将结果添加到result中returnfor i in range(start_index, n + 1):  # 从startindex开始遍历,对应树的横向遍历self.path.append(i)  # 处理节点self.backtracking(n, k, i + 1)  # 递归,对应树的纵向遍历,下一层要从i+1开始,防止出现重复元素self.path.pop()  # 回溯,撤销处理的节点def combine(self, n: int, k: int) -> List[List[int]]:self.backtracking(n, k, 1)return self.result

当n = 4,k = 4的话,那么第一层for循环的时候,从元素2开始的遍历都没有意义了。 在第二层for循环,从元素3开始的遍历都没有意义了。 如图所示:

 

可以剪枝的地方就在递归中每一层的for循环所选择的起始位置如果for循环选择的起始位置之后的元素个数已经不足我们需要的元素个数了,那么就没有必要搜索了

优化过程如下:

  1. 已经选择的元素个数:len(path)

  2. 所需需要的元素个数为: k - len(path)

  3. 列表中剩余元素(n-i) >= 所需需要的元素个数(k - path.size())

  4. 在集合n中至多要从该起始位置 : i <= n - (k - path.size()) + 1,开始遍历

剪枝版本:

class Solution:def combine(self, n: int, k: int) -> List[List[int]]:result = []  # 存放结果集self.backtracking(n, k, 1, [], result)return resultdef backtracking(self, n, k, startIndex, path, result):if len(path) == k:result.append(path[:])returnfor i in range(startIndex, n - (k - len(path)) + 2):  # 优化的地方,range函数是右开的,所以是+2path.append(i)  # 处理节点self.backtracking(n, k, i + 1, path, result)path.pop()  # 回溯,撤销处理的节点

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/577661.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

47 vue 常见的几种模型视图不同步的问题

前言 这里主要是来看一下 关于 vue 中的一些场景下面 可能会出现 模型和视图 不同步更新的情况 然后 这种情况主要是 vue 中的对象 属性没有响应式的 setter, getter 然后 我们这里就来看一下 大多数的情况下的一个场景, 和一些处理方式 当然 处理方式主要是基于 Vue.set, …

4t第14届省赛模拟1

俺服了&#xff0c;原来是\r\n写里边了....... 不过他都测55cm的超声波 是把距离测量值赋给距离参数&#xff0c;俺看反了&#xff0c;然后还加了一个标志位让超声波不进行读取然后显示距离参数值...... 好像用int和char没啥关系&#xff0c;就是后面强制类型转换串口显示都…

机器学习算法的另一个分支-贝叶斯算法原理(贝叶斯要解决什么问题)

目录 一、贝叶斯简介 二、贝叶斯要解决的问题 三、例子&#xff08;公式推导&#xff09; 四、实例 1. 拼写纠正实例 2. 垃圾邮件过滤实例 一、贝叶斯简介 1. 贝叶斯&#xff1a;英国数学家。1702年出生于伦敦&#xff0c;做过神甫。贝叶斯在数学方面主要研究概率论.对于…

『大模型笔记』提示工程、微调和RAG之间对比

提示工程、微调和RAG之间对比 文章目录 一. 提示工程、微调和RAG之间对比二. 参考文章文章:Prompt Engineering vs Finetuning vs RAG一. 提示工程、微调和RAG之间对比 Prompt EngineeringFinetuning

基于springboot的月子会所系统

摘 要 随着时代的进步&#xff0c;人们对生活的要求越来越高。月子基本是每一个生育期的母亲都要精力的一个特殊阶段&#xff0c;在中国人的传统观念中月子是一个非常重要的时期&#xff0c;只有在月子期间得到更好的照顾才能尽快的康复。传统的家庭一般都缺少月子期间对母婴照…

【干货分享】OpenHarmony轻量系统适配方案

1. 简介 本文在不改变原有系统基础框架的基础上&#xff0c; 介绍了一种OpenAtom OpenHarmony&#xff08;以下简称“OpenHarmony”&#xff09;轻量系统适配方案。 本方案使用的是 OpenHarmony v3.2 Release版本源码。 2. 方案设计 本文使用的硬件模块的主要特性及功能如…

4/1 背刺!春招B站一面,这些问题你都会吗?

❝ 下面我将分享一位同学在Bilibili一面的面试经历&#xff0c;对于这次面试&#xff0c;他的评价是&#xff0c;「很有难度」&#xff0c;你试试呢&#xff1f; ❞ 【提醒】通过这次面试经验&#xff0c;你将可以复习到以下知识点&#xff0c;注意汇总&#xff0c;不超过10个 …

git的使用日常习惯规范与一些特殊操作

git的使用日常习惯规范与一些特殊操作 操作习惯规范创建本地新分支&#xff0c;推送新分支到云端仓库1.创建一个本地的login分支2.创建新分支后切换到新分支3.推送新分支到云端 git的特殊操作撤回commit&#xff08;取消提交到本地版本库的动作&#xff0c;本地工作区写的代码不…

c语言游戏实战(7):扫雷

前言&#xff1a; 扫雷是一款经典的单人益智游戏&#xff0c;它的目标是在一个方格矩阵中找出所有的地雷&#xff0c;而不触碰到任何一颗地雷。在计算机编程领域&#xff0c;扫雷也是一个非常受欢迎的项目&#xff0c;因为它涉及到许多重要的编程概念&#xff0c;如数组、循环…

考研数学一——概率论真题——自我总结题型整理(总分393)

系列文章目录 终于考完研了&#xff0c;本人考的是南京航空航天大学的仪器科学与技术&#xff0c;英一数一电路&#xff0c;以下是成绩单&#xff1a; 平时习惯整理自己的学习体系&#xff0c;以下是一个记录。 其实&#xff0c;每个人都应该训练&#xff0c;看到某一类题目…

【Unity】TextMeshPro富文本

启用富文本 在Unity里&#xff0c;如果需要使用富文本&#xff0c;首先需要开启Rich Text 如果不开启Rich Text&#xff0c;就会在UI上显示富文本代码 1.粗体 <b>Game</b> Over2.斜体 <i>Game</i> Over3.下划线 <u>Game</u> Over4…

4G/5G防爆布控球

#防爆布控球 #远程实时监控 #移动应急指挥 #高清图像采集 #防爆安全认证 4G/5G防爆布控球 M130-EX防爆布控球是针对石化装置、石油平台、燃气、化工、制药、煤炭、冶炼、船舶制造、纺织等易燃易爆环境及危险场所而开发设计的防爆智能一体化电气设备。 产品型号&#xff1a;M13…