代码随想录算法训练营第二十九天丨 回溯算法part06

回溯总结

对于回溯算法,我们需要知道的是 回溯是递归的副产品,只要有递归就会有回溯,所有回溯法常与二叉树遍历【前中后序遍历】,深搜混在一起,原因是都涉及到的递归。

回溯法 = 暴力搜索,它的效率并不高,只是我们在递归回溯的时候可以进行剪枝,减少他递归的次数与深度。

回溯算法能解决下列问题:

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

回溯法对我来说还算较为容易理解,但是后面的棋盘问题,像 323.重新安排行程、51.N皇后、37.解数独 都没有什么思路,再看过一遍卡哥的视频讲解之后对于这些题脑子里面还是有些理解了,希望二刷甚至三刷的时候能够a出来,那就真的爽了,哈哈哈。

对于回溯算法,卡哥给了一个模板,基本上所有的回溯就会用到:

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

组合问题

回溯算法:求组合问题! 这是我初入回溯解决的第一道题目,卡哥在文中给我们列举了k层for循环的例子【暴力解法】,递归其实就是可以通过简短的代码实现n层for循环从而进行暴力解题的。

这题卡哥把回溯问题进行了抽象,抽象成了一个树形结构:

对于上图,我们可以很清楚的了解到:for 循环进行横向树层上的遍历,递归纵向进行树枝上的遍历,通过回溯不断调整结果集,进而收集正确的答案。

优化回溯算法 就只有剪枝这一种方法,如图:

剪枝的精髓:

for循环在寻找起点的时候要有一个范围,如果这个起点到集合终止之间的元素已经不够题目要求的k个元素了,就没有必要搜索了

切割问题

回溯算法:分割回文串 (opens new window)中,讲解切割问题,虽然最后代码看起来好像是一道模板题,但是我们从分析到学会套用这个模板,是比较难的。

如下几个难点:

  • 切割问题其实类似组合问题
  • 如何模拟那些切割线
  • 切割问题中递归如何终止
  • 在递归循环中如何截取子串
  • 如何判断回文

如果想到了用求解组合问题的思路来解决 切割问题本题就成功一大半了,接下来就对着模板照葫芦画瓢。

但后序如何模拟切割线,如何终止,如何截取子串,其实都不好想,最后判断回文算是最简单的了

除了这些难点,本题还有细节,例如:切割过的地方不能重复切割所以递归函数需要传入i + 1

树形结构如下:

131.分割回文串

子集问题

在回溯算法:求子集问题! (opens new window)中讲解了子集问题,在树形结构中子集问题是要收集所有节点的结果,而组合问题是收集叶子节点的结果

如图:

78.子集

本题可以不需要加终止条件,因为startIndex >= nums.size(),本层for循环本来也结束了,因为本来我们就要遍历整棵树。

如果要写终止条件,注意:result.push_back(path);要放在终止条件的上面,如下:

result.push_back(path); // 收集子集,要放在终止添加的上面,否则会漏掉结果
if (startIndex >= nums.size()) { // 终止条件可以不加return;
}

排列问题

回溯算法:排列问题! (opens new window)不一样了。

排列是有序的,也就是说 [1,2] 和 [2,1] 是两个集合,这和之前分析的子集以及组合所不同的地方。

可以看出元素1在[1,2]中已经使用过了,但是在[2,1]中还要在使用一次1,所以处理排列问题就不用使用startIndex了。

如图:

46.全排列

此时可以感受出排列问题的不同:

  • 每层都是从0开始搜索而不是startIndex
  • 需要used数组记录path里都放了哪些元素了

本题used数组即是记录path里都放了哪些元素,同时也用来去重,一举两得。

去重问题

之前都是统一使用used数组来去重的,其实使用set也可以用来去重!

在本周小结!(回溯算法系列三)续集 (opens new window)中给出了子集、组合、排列问题使用set来去重的解法以及具体代码。同时详细分析了 使用used数组去重 和 使用set去重 两种写法的性能差异:

使用set去重的版本相对于used数组的版本效率都要低很多!

原因在回溯算法:递增子序列 (opens new window)中分析过,主要是因为程序运行的时候对hashSet 频繁的add,hashSet t需要做哈希映射(也就是把key通过hash function映射为唯一的哈希值)相对费时间,而且 add 的时候其底层的符号表也要做相应的扩充,也是费时的。

而使用used数组在时间复杂度上几乎没有额外负担!

使用set去重,不仅时间复杂度高了,空间复杂度也高了,在本周小结!(回溯算法系列三) (opens new window)中分析过,组合,子集,排列问题的空间复杂度都是O(n),但如果使用set去重,空间复杂度就变成了O(n^2),因为每一层递归都有一个set集合,系统栈空间是n,每一个空间都有set集合。

那我们可能疑惑 用used数组也是占用O(n)的空间啊?

used数组可是全局变量,每层与每层之间公用一个used数组,所以空间复杂度是O(n + n),最终空间复杂度还是O(n)

性能分析

【卡哥的理解】

子集问题分析:

  • 时间复杂度:O(2^n),因为每一个元素的状态无外乎取与不取,所以时间复杂度为O(2^n)
  • 空间复杂度:O(n),递归深度为n,所以系统栈所用空间为O(n),每一层递归所用的空间都是常数级别,注意代码里的result和path都是全局变量,就算是放在参数里,传的也是引用,并不会新申请内存空间,最终空间复杂度为O(n)

排列问题分析:

  • 时间复杂度:O(n!),这个可以从排列的树形图中很明显发现,每一层节点为n,第二层每一个分支都延伸了n-1个分支,再往下又是n-2个分支,所以一直到叶子节点一共就是 n * n-1 * n-2 * ..... 1 = n!。
  • 空间复杂度:O(n),和子集问题同理。

组合问题分析:

  • 时间复杂度:O(2^n),组合问题其实就是一种子集的问题,所以组合问题最坏的情况,也不会超过子集问题的时间复杂度。
  • 空间复杂度:O(n),和子集问题同理。

N皇后问题分析:

  • 时间复杂度:O(n!) ,其实如果看树形图的话,直觉上是O(n^n),但皇后之间不能见面所以在搜索的过程中是有剪枝的,最差也就是O(n!),n!表示n * (n-1) * .... * 1。
  • 空间复杂度:O(n),和子集问题同理。

解数独问题分析:

  • 时间复杂度:O(9^m) , m是'.'的数目。
  • 空间复杂度:O(n^2),递归的深度是n^2

一般说道回溯算法的复杂度,都说是指数级别的时间复杂度,这也算是一个概括吧!

回溯专题汇聚为一张图:


上述是根据卡哥的总结及自己的一些了解的综合,自己的语言组织能力较弱,很多都是直接抄卡哥的,有错误望指正。

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

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

相关文章

从北京到南京:偶数在能源行业的数据迁移实践

能源行业的数字化转型 当前,大数据技术在以电力为代表的能源行业不断推进,同时,分布式能源、储能、电网技术不断改进,电力行业的数字化转型充满了机遇和挑战。 一方面,电力行业本身自动化程度高、信息化基础好、系统…

文件夹图片相似图片检测并删除相似图片

项目开源地址 pip install imagededupgit clone https://github.com/idealo/imagededup.git cd imagededup pip install "cython>0.29" python setup.py installQuick Start from imagededup.methods import PHash phasher PHash()# Generate encodings for all…

macOS Tor 在启动期间退出

macos Tor 在启动期间退出。这可能是您的 torrc 文件存在错误,或者 Tor 或您的系统中的其他程序存在问题,或者硬件问题。在您解决此问题并重新启动 Tor 前,Tor 浏览器将不会启动。退出Tor、卸载Tor、删除目录 TorBrowser-Data、重启电脑 访…

系统设计 - 我们如何通俗的理解那些技术的运行原理 - 第二部分:CI CD、设计模式、数据库

本心、输入输出、结果 文章目录 系统设计 - 我们如何通俗的理解那些技术的运行原理 - 第二部分:CI CD、设计模式、数据库前言CI/CD第 1 部分 - 带有 CI/CD 的 SDLC第 2 部分 - CI 和 CD 之间的区别第 3 部分 - CI/CD 管道 Netflix Tech Stack (CI/CD Pip…

在模拟冷藏牛肉加工条件下,冷和酸对荧光假单胞菌和单核细胞增生李斯特菌双菌种生物膜的综合影响

1.1 Title:Combined effects of cold and acid on dual-species biofilms of Pseudomonas fluorescens and Listeria monocytogenes under simulated chilled beef processing conditions 1.2 分区/影响因子:Q1/5.3 1.3 作者:Zhou Guanghui…

哪个牌子的台灯对孩子的视力好?对孩子视力好的台灯推荐分享

现在市面上台灯品牌众多,价格不一,品质更是参差不齐,所以要学会如何选择适合孩子的台灯。光源质量是重要因素,光源是直接影响到孩子的视力, 一般来说,光源质量主要看照度、亮度和均匀度、显色指数等&#x…

大语言模型在推荐系统的实践应用

本文从应用视角出发,尝试把大语言模型中的一些长处放在推荐系统中。 01 背景和问题 传统的推荐模型网络参数效果较小(不包括embedding参数),训练和推理的时间、空间开销较小,也能充分利用用户-物品的协同信号。但是它的缺陷是只能利用数据…

softplc windows 安装测试

下载 .NET 6.0 (Linux、macOS 和 Windows) 安装后 在这里 The command could not be loaded, possibly because: * You intended to execute a .NET application: The application restore does not exist. * You intended to execute a .NET SDK command: No…

海外版知乎Quora,如何使用Quora进行营销?

想必大家对知乎非常熟悉,而Quora作为海外最受欢迎的网站之一,是与知乎功能与性质非常相似的一个平台,靠回答别人的问题获得关注,是引流最快的一个平台。对于做跨境电商、独立站的商家来说,这是一个绝佳的免费引流广告工…

小程序canvas层级过高真机遮挡组件的解决办法

文章目录 问题发现真机调试问题分析问题解决改造代码效果展示 问题发现 在小程序开发中需要上传图片进行裁剪&#xff0c;在实际真机调试中发现canvas层遮挡住了生成图片的按钮。 问题代码 <import src"../we-cropper/we-cropper.wxml"></import> <…

2023.10.19 关于 单例模式 详解

目录 引言 单例模式 饿汉模式 懒汉模式 懒汉模式线程安全问题 分析原因 引言 设计模式为编写代码的 约定 和 规范 阅读下面文章前建议点击下方链接明白 对象 和 类对象 对象和类对象 单例模式 单个实例&#xff08;对象&#xff09;在某些场景中有特定的类&#xff0c;…

IntelliJ IDEA 2020.2.1白票安装使用方法

先安装好idear Plugins 内手动添加第三方插件仓库地址&#xff1a;https://plugins.zhile.io 搜索&#xff1a;IDE Eval Reset插件进行安装 输入https://plugins.zhile.io 手动安装离线插件方法 安装包可以去笔者的CSDN资源库下载 安装mybaties插件

Java版ORM最初雏形

经过一个晚上的加班&#xff0c;终于把ORM初步结构工程搭好了。工程依赖有点难用&#xff0c;编辑器提示比VS差很多。 首先LIS.Core创建一个最初的容器雏形&#xff0c;先能反射得到对象给ORM获得数据库驱动 然后ORM创建数据库驱动差异接口&#xff0c;不同数据库实现接口后配…

uniapp vue3 使用pinia存储 并获取数据

存token import { defineStore } from pinia;export const userInfo defineStore(userInfo, {state: () > {return {userToken: uni.getStorageSync(token) || ,};},actions: {// 添加tokenupdateToken(token: string) {uni.setStorageSync(token, token);this.userToken…

蓝牙音视频远程控制协议(AVRCP)介绍

零.声明 本专栏文章我们会以连载的方式持续更新&#xff0c;本专栏计划更新内容如下&#xff1a; 第一篇:蓝牙综合介绍 &#xff0c;主要介绍蓝牙的一些概念&#xff0c;产生背景&#xff0c;发展轨迹&#xff0c;市面蓝牙介绍&#xff0c;以及蓝牙开发板介绍。 第二篇:Trans…

【六:pytest框架介绍】

常见的请求对象requests.get()requests.post()requests.delete()requests.put()requests.request()常见的响应对象reprequests.request()//返回字符串格式数据print(req.text)//返回字节格式数据print(req.content)//返回字典格式数据print(req.json)#状态码print(req.status_c…

Character Animator 2024(Ch2024):打造生动角色,让动画设计更上一层楼

Character Animator 2024是一款专为角色动画设计师打造的软件&#xff0c;它可以帮助设计师快速创建出丰富多彩的角色动画。无论是初学者还是专业设计师&#xff0c;都可以通过Character Animator 2024轻松实现自己的创意。 Ch2024独特优势&#xff1a; 实时角色动画&#xf…

计算机网络 | 应用层

计算机网络 | 应用层 计算机网络 | 应用层应用层概述网络应用模型客户/服务器模型&#xff08;Client/Server&#xff0c;C/S&#xff09;P2P模型&#xff08;Peer-to-Peer&#xff09; 域名系统&#xff08;DNS&#xff09;层次域名空间域名服务器域名解析过程 文件传输协议&a…

DevExpress WPF Pivot Grid组件,可轻松实现多维数据分析!(二)

在上文中&#xff08;点击这里回顾>>&#xff09;我们主要为大家介绍了DevExpress WPF Pivot Grid组件的超快速枢轴分析功能、Microsoft分析服务等&#xff0c;本文将继续介绍图表透视数据的处理、MVVM支持等。欢迎持续关注我们&#xff0c;探索更多新功能哦~ P.S&#…

【工具】利用ffmpeg将网页中的.m3u8视频文件转化为.mp4格式

目录 0.环境 1.背景 2.前提 3.详细描述 1&#xff09;在网站上找到你想下载的视频的.m3u8链接 2&#xff09;打开命令行&#xff0c;用ffmpeg命令进行转化 3&#xff09;过程&结果截图 0.环境 windows64 ffmpeg 1.背景 网页上有个.m3u8格式的视频文件&#xff0c;…