【蓝桥杯速成】| 8.回溯算法

因为在进行背包问题的练习时,发现很多题目需要回溯,但本人作为小白当然是啥也不知道

那么就先来补充一下回溯算法的知识点,再进行练习

理论基础

回溯算法本质上是一种递归函数,是纯暴力搜索方法,

适合组合问题、排列问题、切割问题、子集问题,棋盘问题

常见题目如:回文子串,N皇后,解数读

回溯法可以抽象为一个树形结构

对于每个结点处理的集合大小通常用for循环进行遍历

对于树的深度就是递归的深度,用递归处理

回溯算法模板!

void backtracking (参数){

        if(终止条件){

                在叶子结点收集结果;

                return;

        }

        for(集合元素){//遍历结点内元素

                处理结点;

                backtracking;//递归函数

                回溯操作;//撤销处理结点的情况

        }

        return;

}

        


题目一:组合

问题描述

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

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

解题步骤

在n和k都较小的情况下,我们利用嵌套for循环就能解决

但如果n,k都比较大,那么我们就需要嵌套k个循环,

这是非常不合理的,代码编写也没有那么容易

那么我们就需要使用回溯算法,利用递归解决多层循环嵌套

具体操作就按照回溯三部曲来进行(其实和递归三部曲是一样的)

1.确定递归函数的返回值以及参数

套用模板,返回值一般都是void,特事特办才需要修改,本题不需要

我们要处理多个数字,组合得到目标个数的结果

那么数字范围要作为参数,目标个数也需要,

同时,组合是没有次序区别的,

所以为了避免重复,我们需要加入一个不断递增量改动开始位置startindex

void backtracking(int n, int k, int startIndex)

为了方便得到结果与存放过程量

可以定义两个全局变量

vector<vector<int>> result; // 存放符合条件结果的集合
vector<int> path; // 用来存放符合条件结果

2.明确回溯终止条件

根据我们的推理,最后我们希望得到的是长度为k的数字组合

每一层递归将会往组合中加入一个数字,需要k个就要递归k次

每次的路径决定数字,逐渐形成path,成形后把整个path加入最后要返回的大集合result里

if(path.size()==k){

        result.push_back(path);

        return;

3.单层搜索过程

第一层,我们需要从1开始,遍历到1就加入path,再进入递归函数选择出下一个数字

那么下一个数字只能从2开始选择,选择完毕需要再加入这个结点,以供下一个数字开头时使用

那么外层就是很简单从1开始遍历到n给每个数字一个做开头的机会(只是这样不会弄错弄乱,避免出现少考虑的情况,实际上没有顺序意义)

for (int i = startIndex; i <= n; i++) { // 控制树的横向遍历
    path.push_back(i); // 处理节点
    backtracking(n, k, i + 1); // 递归:控制树的纵向遍历,注意下一层搜索要从i+1开始
    path.pop_back(); // 回溯,撤销处理的节点
}

那么这个和回溯模板基本一样的经典题关键代码已经完成!

最后在写一下主函数,完善一下逻辑即可

vector<vector<int>> combine(int n, int k) {
        result.clear(); // 可以不写
        path.clear();   // 可以不写
        backtracking(n, k, 1);
        return result;
    }

 完整代码如下!

code

class Solution {
public:vector<int> path;vector<vector<int>> result;void backtracking(int n,int k,int startindex){if(path.size()==k){result.push_back(path);return;}for(int i=startindex;i<=n;i++){path.push_back(i);backtracking(n,k,i+1);path.pop_back();}}vector<vector<int>> combine(int n, int k) {backtracking(n,k,1);return result;}
};

ok想必大家发现这个程序其实可以改进一下,

例如n=4,k=2时,当这个n遍历到4时其实就咩有必要了,没有数字可供他选择组合

所以在这个遍历终点处,我们可以进行一下剪枝优化

目前组合长度为:path.size(),这个值是从0开始的

还需要数字个数为:k - path.size()

列表剩余数字个数为:n - i, i 是从1开始的

应该让 剩余大于等于需要:n - i >= k - path.size() + 1(+1是为了统一两边步调)

变化一下不等式:i <= n - (k - path.size() )- 1

那么这个循环就变为了

for (int i = startindex; i <= n - (k - path.size()) + 1; i++){

 全部代码只需要改动这一行就可以避免很多不必要的操作,减少浪费


题目二:组合总和③

问题描述

216. 组合总和 III - 力扣(LeetCode)

找出所有相加之和为 n 的 k 个数的组合,且满足下列条件:

  • 只使用数字1到9
  • 每个数字 最多使用一次 

返回 所有可能的有效组合的列表 。该列表不能包含相同的组合两次,组合可以以任何顺序返回。

解题步骤

这一题和上一题有很多相似之处,

区别在于,固定数字范围[1,9],给出目标和 n

那么我们可以用同样的思路现在1~9中找出包含k个数的所有组合

再通过计算,求和与目标和进行比较,如果相等则加入到最后的result数组中

同时呢,由于我们只需要在9个数字中取舍,优化的效果就没那么大了,可以不用

所以动手操作下来,在终止条件中加上sum==n,并在这之前执行sum计算即可

int sum=accumulate(path.begin(),path.end(),0);

        if(path.size()==k && sum==n){

完整代码如下! 

code

class Solution {
public:vector<int> path;vector<vector<int>> result;void backstacking(int k,int n,int startindex){int sum=accumulate(path.begin(),path.end(),0);if(path.size()==k && sum==n){result.push_back(path);return;}for(int i=startindex;i<=9;i++){path.push_back(i);backstacking(k,n,i+1);path.pop_back();}}vector<vector<int>> combinationSum3(int k, int n) {backstacking(k,n,1);return result;}
};

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

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

相关文章

IDEA 快捷键ctrl+shift+f 无法全局搜索内容的问题及解决办法

本篇文章主要讲解IDEA、phpStrom、webStrom、pyCharm等jetbrains系列编辑器无法进行全局搜索内容问题的主要原因及解决办法。 日期&#xff1a;2025年3月22日 作者&#xff1a;任聪聪 现象描述&#xff1a; 1.按下ctrlshiftf 输入法转为了繁体。 2.快捷键ctrlshiftr 可以全局检…

2025年- G24-Lc98-217.包含重复(使用hashSet解决)-java版

1.题目描述 2.思路 思路一&#xff1a; 我的想法是直接用集合来判断&#xff0c;如果集合的元素不能添加说明之前已经存在这个元素&#xff0c;也就是发现了重复元素&#xff0c;所以返回false。 补充一&#xff1a; Map、ArrayList的定义和声明 3.代码实现 class Soluti…

MySQL事务全解析:从概念到实战

在数据库操作中&#xff0c;事务是一个至关重要的概念&#xff0c;它确保了数据的完整性和一致性。今天&#xff0c;就让我们深入探讨MySQL事务的方方面面&#xff0c;从基础概念到实际应用&#xff0c;全面掌握这一技能。 一、为什么需要事务 假设张三要给李四转账100元&…

CVPR 2025 | 文本和图像引导的高保真3D数字人高效生成GaussianIP

小小宣传一下CVPR 2025的工作GaussianIP。 arXiv&#xff1a;https://arxiv.org/abs/2503.11143 Github&#xff1a;https://github.com/silence-tang/GaussianIP 欢迎star, issue~ 摘要 文本引导的3D人体生成随着高效3D表示及2D升维方法&#xff08;如SDS&#xff09;的发展…

Model Context Protocol:下一代AI系统集成范式革命

在2023年全球AI工程化报告中,开发者面临的核心痛点排名前三的分别是:模型与业务系统集成复杂度(58%)、上下文管理碎片化(42%)、工具调用标准化缺失(37%)。传统API集成模式在对接大语言模型时暴露明显短板:RESTful接口无法承载动态上下文,GraphQL缺乏工具编排能力,gR…

多模态大模型常见问题

1.视觉编码器和 LLM 连接时&#xff0c;使用 BLIP2中 Q-Former那种复杂的 Adaptor 好还是 LLaVA中简单的 MLP 好&#xff0c;说说各自的优缺点&#xff1f; Q-Former&#xff08;BLIP2&#xff09;&#xff1a; 优点&#xff1a;Q-Former 通过查询机制有效融合了视觉和语言特征…

EasyRTC轻量级Webrtc音视频通话SDK,助力带屏IPC在嵌入式设备中的应用

一、市场背景 随着人们生活水平的提高&#xff0c;对于家居安全和远程监控的需求日益增长&#xff0c;带屏IPCam不仅满足了用户实时查看监控画面的需求&#xff0c;还提供了诸如双向语音通话、智能报警等丰富的功能&#xff0c;极大地提升了用户体验。 此外&#xff0c;技术的…

Linux安装JDK

1、下载JDK https://www.oracle.com/cn/java/technologies/downloads/#java11 2、安装 2.1、创建安装目录 mkdir /usr/local/jdk 2.1、将下载的tar.gz上传到服务器 使用tar -zxvf jdk-8u311-linux-x64.tar.gz解压后剪切到 /usr/local/jdk目录&#xff1a;mv xxx /usr/local/j…

基于基于eFish-SBC-RK3576工控板的智慧城市边缘网关

此方案充分挖掘eFish-SBC-RK3576的硬件潜力&#xff0c;可快速复制到智慧园区、交通枢纽等场景。 方案亮点 ‌接口高密度‌&#xff1a;单板集成5GWiFi多路工业接口&#xff0c;减少扩展复杂度。‌AIoT融合‌&#xff1a;边缘端完成传感器数据聚合与AI推理&#xff0c;降低云端…

CSS 学习笔记 - 蓝桥杯重点整理

1. CSS 基础语法 核心知识点 选择器 声明块结构三种引入方式&#xff1a;行内/内部/外部常用选择器类型&#xff1a;标签/类/ID/通配符 <!-- 行内样式 --> <p style"color: red;">红色文字</p><!-- 内部样式 --> <style>/* 标签选…

UML的使用

process on 在线使用 UML概念 UML &#xff1a;统一建模语言(Unified Modeling Language&#xff0c;是用来设计软件的可视化建模语言。 1. 类图 1.1 概念 类图&#xff08;Class Diagram&#xff09;是UML中用于描述系统静态结构的图形化工具。它展示了系统的类、接口、它…

【C++】入门

1.命名空间 1.1 namespace的价值 在C/C中&#xff0c;变量&#xff0c;函数和后面要学到的类都是大量存在的&#xff0c;这些变量&#xff0c;函数和类的名称将存在于全局作用域中&#xff0c;可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化&#xff0c;…

数据库练习2

目录 1.向heros表中新增一列信息&#xff0c;添加一些约束&#xff0c;并尝试查询一些信息 2.课堂代码练习 插入语句 INSERT INTO 删除语句DELETE和TRUNCATE 更新语句UPDATE和replace 查询语句SELECT 条件查询 查询排序 聚合函数 分组查询 3.题目如下 一、单表查询 …

w266农产品直卖平台的设计与实现

&#x1f64a;作者简介&#xff1a;多年一线开发工作经验&#xff0c;原创团队&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的网站项目。 代码可以查看文章末尾⬇️联系方式获取&#xff0c;记得注明来意哦~&#x1f339;赠送计算机毕业设计600个选题excel文…

2025新版懒人精灵零基础安装调试+lua基础+UI设计交互+常用方法封装+项目实战+项目打包安装板块-视频教程(初学者必修课)

2025新版懒人精灵零基础安装调试lua基础UI设计交互常用方法封装项目实战项目打包安装板块-视频教程(初学者必修课)&#xff1a; 1.懒人精灵核心API基础和lua基础视频教程&#xff1a;https://www.bilibili.com/video/BV1Vm9kYJEfM/ 温馨提示&#xff1a;所有视频请用电脑浏览…

CCF-CSP认证 202206-2寻宝!大冒险!

题目描述 思路 有一张绿化图和藏宝图&#xff0c;其中绿化图很大&#xff08;二维数组在限定的空间内无法存储&#xff09;&#xff0c;而藏宝图是绿化图中的一部分&#xff0c;对于绿化图和藏宝图&#xff0c;左下角的坐标为(0, 0)&#xff0c;右上角的坐标是(L, L)、(S, S)&…

Qt下集成大华网络相机SDK示例开发

文章目录 前言一、下载并集成大华网络相机SDK二、示例实现功能三、示例完整代码四、下载链接总结 前言 近期在Qt环境下进行大华网络相机的使用&#xff0c;发现官网下载的SDK中提供的示例没有Qt的demo&#xff0c;通过学习其提供的MFC示例代码&#xff0c;我在这里也实现了一个…

[学习笔记] 部署Docker搭建靶场

前言 我们需要部署Docker来搭建靶场题目&#xff0c;他可以提供一个隔离的环境&#xff0c;方便在不同的机器上部署&#xff0c;接下来&#xff0c;我会记录我的操作过程&#xff0c;简单的部署一道题目 Docker安装 不推荐在物理机上部署&#xff0c;可能会遇到一些问题&…

网络华为HCIA+HCIP IPv6

目录 IPv4现状 IPv6基本报头 IPv6扩展报头 IPv6地址 IPv6地址缩写规范 ​编辑 IPv6地址分配 IPv6单播地址分配 IPv6单播地址接口标识 IPv6常见单播地址 - GUA &#xff08;2 / 3 开头&#xff09; IPv6常见单播地址 - ULA IPv6常见单播地址 - LLA IPv6组播地…

可视化动态表单动态表单界的天花板--Formily(阿里开源)

文章目录 1、Formily表单介绍2、安装依赖2.1、安装内核库2.2、 安装 UI 桥接库2.3、Formily 支持多种 UI 组件生态&#xff1a; 3、表单设计器3.1、核心理念3.2、安装3.3、示例源码 4、场景案例-登录注册4.1、Markup Schema 案例4.2、JSON Schema 案例4.3、纯 JSX 案例 1、Form…