算法力扣刷题记录 六十三【回溯章节开篇】

前言

开始回溯章节学习。

在二叉树中预先体会了回溯。那么回溯单独来说是怎么回事?


一、基础知识学习

回溯基础知识参考链接

在这里插入图片描述


二、组合问题

2.1题目阅读

给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 k 个数的组合。

你可以按 任何顺序 返回答案。

示例 1:

输入:n = 4, k = 2
输出:
[[2,4],[3,4],[2,3],[1,2],[1,3],[1,4],
]

示例 2:

输入:n = 1, k = 1
输出:[[1]]

提示:

1 <= n <= 20
1 <= k <= n

2.2尝试实现

思路

  1. 题目就是组合,解决组合问题想到回溯算法。穷举每一个选项。

  2. 确定该集合的树形结构:以示例一为例——如下图:
    在这里插入图片描述

  3. 利用回溯模版开始填充逻辑——

  • 确定函数的返回值:void。用vector<vector > result放结果,所以无需返回值,直接搜集。
  • 确定函数参数:
    • int n用来限定一个树的横向范围;
    • int k 终止条件需要。当中间vector< int > temp.size() == k,放入result中;
    • int num,当前层从num开始循环。如图红色线的一条递归路径:第一层从1开始;第二层从2开始;第三层从3开始;第四层从4开始。结合n确定本层有几个孩子
    • vector< int >& temp放中间结果,引用形式;
    • vector<vector > result主函数的返回值,引用形式;
  • 确定终止条件:在分析参数int k时,已经指出终止条件:vector< int > temp.size() == k。终止逻辑:result.push_back(temp);
  • 中间的逻辑:
    • for循环的起始终止:i = num+1;i <= n;i++ 。以第一个树来说:第一层的孩子:2,3,4;第二层节点2的孩子:3,4;第三次节点3的孩子:4.
    • 调用本回溯(递归)函数;
    • temp.pop_back();回溯操作,删除下一层加入temp的元素。
  1. 递归函数完成之后,发现主函数中也需要for循环替换下一个树。

(对照代码)

代码实现

class Solution {
public:void backtracking(int n,int k,int num,vector<int>& temp,vector<vector<int>>& result){temp.push_back(num);//放入该层节点if(temp.size() == k){result.push_back(temp);//搜集结果return;}for(int i = num+1;i <= n;i++){//处理孩子backtracking(n,k,i,temp,result);temp.pop_back();//回溯,弹出下一层放入的元素}return;}vector<vector<int>> combine(int n, int k) {vector<vector<int>> result;vector<int> temp;for(int i=1;i <= n;i++){backtracking(n,k,i,temp,result);temp.clear();//第一层的清空。}return result;}
};

所以,本代码的第一层是在主函数中控制。第二层之后在递归(回溯)函数中实现。

体会回溯

回溯其实不是一个函数,整个函数不是只完成回溯,回溯其实是一个操作:temp.pop_back();只这一行是回溯。

整个函数是一个递归,但是递归当前层中有for循环,从下层回归到本层进行回溯操作。


2.3 参考学习

参考学习链接

  1. 参考给的思路:按照一、基础知识学习的递归模版完成。抽象成一个树的结构。参考给的树:
    在这里插入图片描述
  2. 所以2.2尝试实现参考的区别:第一层直接在递归函数中完成,主函数中没有for循环控制第一层。
  3. 参考代码实现:(在2.2尝试实现上改进)
class Solution {
public:void backtracking(int n,int k,int num,vector<int>& temp,vector<vector<int>>& result){//终止条件:当temp中间结果个数等于目标组合个数,放入最终结果集中if(temp.size() == k){result.push_back(temp);//搜集结果return;}//num就是参考中的startindexfor(int i = num;i <= n;i++){//从num开始。temp.push_back(i);//放入本层元素。//处理孩子,深入递归backtracking(n,k,i+1,temp,result);//递的时候给i+1temp.pop_back();//归的时候回溯,弹出下一层放入的元素}return;}vector<vector<int>> combine(int n, int k) {vector<vector<int>> result;vector<int> temp;backtracking(n,k,1,temp,result);return result;}
};
  1. 剪枝优化:怎么剪?如何剪?剪枝优化参考讲解。
    但为什么for循环的终止条件是n-(k-path.size())+1的规律再展现一遍
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 解释n-(k-path.size())+1是for的终止条件:
    • 集合个数n说明完整的树结构有n层;
    • k-path.size()代表组合temp中现在还缺多少个元素;注意本层元素添加是在for循环内部,此时还没有加入本次元素。
    • n-(k-path.size())+1代表能抵达第k层的路径范围。集合总数n减去后面(k-path.size())个元素,前面剩下的是已经选择的路径。再加1是因为这个路径选择能抵达k。(看下图红色文本栏对数组颜色的区分)。
      在这里插入图片描述
  1. 剪枝优化的代码把for循环的终止条件改了,缩小for循环的终止范围
class Solution {
public:void backtracking(int n,int k,int num,vector<int>& temp,vector<vector<int>>& result){//终止条件:当temp中间结果个数等于目标组合个数,放入最终结果集中if(temp.size() == k){result.push_back(temp);//搜集结果return;}//num就是参考中的startindexfor(int i = num;i <= n-(k-temp.size())+1;i++){//从num开始。temp.push_back(i);//放入本层元素。//处理孩子,深入递归backtracking(n,k,i+1,temp,result);//递的时候给i+1temp.pop_back();//归的时候回溯,弹出下一层放入的元素}return;}vector<vector<int>> combine(int n, int k) {vector<vector<int>> result;vector<int> temp;backtracking(n,k,1,temp,result);return result;}
};

总结

在这里插入图片描述

(欢迎指正,转载标明出处)

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

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

相关文章

【C++入门(上)】—— 我与C++的不解之缘(一)

前言&#xff1a; 学完C语言和初阶数据结构&#xff0c;感觉自己又行了&#xff1f; 接下来进入C的学习&#xff0c;准备好接受头脑风暴吧。 一、第一个C程序 C 的第一个程序&#xff0c;梦回出学C语言&#xff0c;第一次使用C语言写代码&#xff1b;这里使用C写第一个C代码。 …

对优先级队列(堆)的理解

目录&#xff1a; 一. 优先级队列&#xff1a; 二. 优先级队列的模拟实现&#xff1a; 三.常用接口介绍: 一. 优先级队列&#xff1a; 1 概念&#xff1a; 队列是一种先进先出的数据结构&#xff0c;但有些情况下&#xff0c;操作的数据可能带有优先级&#xff0c;一般出队列时…

Linux系统目录结构

Linux系统下一切皆文件 &#xff01;&#xff01;&#xff01; 系统启动必须: /boot : 存放启动Linux时所需的内核文件&#xff0c;包括压缩后的内核镜像文件(vmlinuz)、虚拟文件系统镜像文件(initrd.img)、启动引导grub的配置文件。/etc : 系统全局配置文件&#xff0c;会影…

从Excel高手到SQL大师-解锁数据分析的无限潜力 -10分钟读懂职场必备技能

目录 Excel 和 SQL&#xff1a;看似相似却大不相同的数据处理利器Excel vs SQL&#xff1a;表面相似&#xff0c;本质迥异Excel&#xff1a;直观但受限的电子表格SQL&#xff1a;强大而灵活的数据库查询语言 从 Excel 到 SQL&#xff1a;跨越鸿沟Excel 数据筛选SQL 数据筛选 结…

基于 Kafka 的经验:AutoMQ 和 MinIO 如何解决成本和弹性挑战

Apache Kafka 因其出色的设计和强大的功能而成为流式处理的事实标准。它不仅定义了现代流式处理的架构&#xff0c;而且其独特的分布式日志抽象还为实时数据流处理和分析提供了前所未有的功能。Kafka 的成功在于它能够满足高吞吐量和低延迟的数据处理需求&#xff0c;多年来&am…

论文阅读:Most Probable Densest Subgraphs

摘要 本文提出了一种在不确定图中发现最有可能稠密子图&#xff08;MPDS&#xff09;的新方法。不确定图中的每条边都有存在概率&#xff0c;使得计算稠密子图变得複杂。作者定义了稠密子图概率&#xff0c;并证明了计算该概率是#P难的。为了解决这个问题&#xff0c;设计了基…

数据科学 - 数据预处理 (数据清洗,结构化数据)

1. 前言 数据清洗与结构化数据在数据分析和机器学习项目中扮演着至关重要的角色。随着大数据时代的到来&#xff0c;数据的质量、准确性和可用性成为决定项目成功与否的关键因素。 数据清洗提高数据质量&#xff0c;保证数据集的一致性&#xff1b;促进数据分析与挖掘&#xf…

【大数据开发语言Scala的入门教程】

🎥博主:程序员不想YY啊 💫CSDN优质创作者,CSDN实力新星,CSDN博客专家 🤗点赞🎈收藏⭐再看💫养成习惯 ✨希望本文对您有所裨益,如有不足之处,欢迎在评论区提出指正,让我们共同学习、交流进步! 🪁Scala 🪡Scala是一种功能丰富且具有强大表达能力的静态类型…

【2024蓝桥杯/C++/B组/传送阵】

题目 问题代码 #include<bits/stdc.h> using namespace std;const int N 1e610; int n; int porter[N]; int ans; int sign[N]; bool used;void dfs(int now, int cnt) {if(sign[now] && used){ans max(ans, cnt);return;}if(!sign[now]){cnt, sign[now] 1; …

成为git砖家(8): 使用 git log 查询范围内的 commit

文章目录 1. 查询 git log 的文档2. 不带任何参数: git log 啥意思&#xff1f;3. git log 最主要功能是什么&#xff1f;4. git log <commit1>..<commit2> 什么意思5. 查看最近n次commit6. References 1. 查询 git log 的文档 git help log --web市面上针对 git …

ubuntu sudo命令不需要密码

sudo vim /etc/sudoers1、注释掉 %sudo ALL(ALL:ALL) AL 2、添加 用户名 ALL(ALL:ALL) NOPASSWD:ALL保存&#xff0c;退出即可

NineData云原生智能数据管理平台新功能发布|2024年7月版

本月发布 12 项更新&#xff0c;其中性能优化 3 项、功能优化 8 项、安全性发布 1 项。 1. 性能优化 数据复制 - SQL Server 增量性能优化 调整读取和写入方式&#xff0c;让 SQL Server 增量复制的性能轻松达到 5000 RPS 以上。 数据复制 - Doris|SelectDB|StarRocks 性能优…

链式二叉树的实现

文章目录 &#x1f3af;引言&#x1f453;链式二叉树的实现1.链式二叉树的结构2.链式二叉树相关操作实现2.1源码展示2.2函数实现详解2.2.1前中后序遍历2.2.2二叉树的其他方法实现2.2.3二叉树的层序遍历和判断是否是完全二叉树 &#x1f947;结语 &#x1f3af;引言 欢迎来到Ha…

【多模态大模型】 BLIP-2 in ICML 2023

一、引言 论文&#xff1a; BLIP-2: Bootstrapping Language-Image Pre-training with Frozen Image Encoders and Large Language Models 作者&#xff1a; Salesforce Research 代码&#xff1a; BLIP-2 特点&#xff1a; 该方法分别使用冻结的图像编码器&#xff08;ViT-L/…

全球氢钎焊市场规划预测:未来六年CAGR为3.4%

随着全球制造业的持续发展和消费者对高质量产品的需求增加&#xff0c;氢钎焊作为一种高效的焊接技术&#xff0c;正逐渐受到市场的广泛关注。本文旨在通过深度分析氢钎焊行业的各个维度&#xff0c;揭示行业发展趋势和潜在机会。 【市场趋势的演变】 1. 市场规模与增长&#…

C++自定义接口类设计器之可对称赋值三

关键代码 QStringList newLines;for (const auto& line : lines) {auto equalIndex line.indexOf("");if(-1 ! equalIndex) {// a b; 赋值auto var line.mid(0, equalIndex).trimmed();auto value line.mid(equalIndex 1).trimmed();if(value.endsWith(&quo…

【网络安全】副业兼职日入12k,网安人不接私活就太可惜了!

暑假来了&#xff0c;很多同学后台私信我求做兼职的路子&#xff0c;这里&#xff0c;我整理了一份详细攻略&#xff0c;请大家务必查收&#xff0c;这可能会帮你把几个学期的生活费都赚够&#xff01; Up刚工作就开始做挖漏洞兼职&#xff0c;最高一次赚了12k&#xff0c;后面…

STM32Cubemx在FreeRTOS中使用面向对象的方式使用串口

文章目录 前言一、创建FreeRTOS工程二、创建文件对串口进行封装三、代码编写总结 前言 本篇文章将带大家来学习使用面向对象的方式在FreeRTOS中使用串口&#xff0c;使用面向对象的方法非常适合编写可移植性强的代码&#xff0c;那么这篇文章就带大家来看一下这个代码要怎么写…

模型 正态分布(通俗解读)

系列文章 分享 模型&#xff0c;了解更多&#x1f449; 模型_思维模型目录。随机世界的规律&#xff0c;大自然里的钟形曲线。 1 正态分布的应用 1.1 质量管理之六西格玛 六西格玛是一种旨在通过识别和消除缺陷原因来提高制造过程或业务流程质量的管理策略。我们先来了解下六…

CX32L003F8P6T芯片解密程序破解

CX32L003F8P6T可替代N76E003 CX32L003是一款内嵌32位ARM Cortex-M0内核的超低功耗、Low Pin Count和宽电压工作范围(2.5V~5.5V)的微控制器&#xff0c;最高可运行在24MHz&#xff0c;内置32K/64K字节的嵌入式Flash&#xff0c;4K字节的SRAM&#xff0c;集成了12位1Msps高精度SA…