代码随想录笔记--回溯算法篇

news2024/10/1 2:30:02

1--回溯算法理论基础

        回溯算法本质上是一个暴力搜索的过程,其常用于解决组合切割子集排列等问题,其一般模板如下:

void backTracking(参数){
    if(终止条件){
    // 1. 收获结果;
    // 2. return;
    }

    for(..遍历){
        // 1. 处理节点
        // 2. 递归搜索
        // 3. 回溯 // 即撤销对节点的处理
    }
    return;
}

2--组合问题

主要思路:

        基于回溯法,暴力枚举 k 个数,需注意回溯弹出元素的操作;

#include <iostream>
#include <vector>

class Solution {
public:
    std::vector<std::vector<int>> combine(int n, int k) {
        std::vector<int> path;
        backTracking(n, k, path, 1); // 从第 1 个数开始
        return res;
    }

    void backTracking(int n, int k, std::vector<int> path, int start){
        if(path.size() == k){
            res.push_back(path);
            return;
        }

        for(int i = start; i <= n; i++){
            path.push_back(i);
            backTracking(n, k, path, i + 1); // 递归暴力搜索下一个数
            path.pop_back(); // 回溯
        }
    }

private:
    std::vector<std::vector<int>> res;
};

int main(int argc, char* argv[]){
    int n = 4, k = 2;
    Solution S1;
    std::vector<std::vector<int>> res = S1.combine(n, k);
    for(auto v : res){
        for(int item : v) std::cout << item << " ";
        std::cout << std::endl;
    }
    return 0;
}

3--组合问题的剪枝操作

        上题的组合问题中,对于进入循环体 for(int i = start; i <= n; i++):

已选择的元素数量为:path.size()

仍然所需的元素数量为:k - path.size()

剩余的元素集合为:n - i + 1

则为了满足要求,必须满足:k-path.size() <= n - i + 1,即 i <= n - k + path.size() + 1

因此,可以通过以下条件完成剪枝操作:

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

#include <iostream>
#include <vector>

class Solution {
public:
    std::vector<std::vector<int>> combine(int n, int k) {
        std::vector<int> path;
        backTracking(n, k, path, 1); // 从第 1 个数开始
        return res;
    }

    void backTracking(int n, int k, std::vector<int> path, int start){
        if(path.size() == k){
            res.push_back(path);
            return;
        }

        for(int i = start; i <= n - k + path.size() + 1; i++){
            path.push_back(i);
            backTracking(n, k, path, i + 1); // 暴力下一个数
            path.pop_back(); // 回溯
        }
    }

private:
    std::vector<std::vector<int>> res;
};

int main(int argc, char* argv[]){
    int n = 4, k = 2;
    Solution S1;
    std::vector<std::vector<int>> res = S1.combine(n, k);
    for(auto v : res){
        for(int item : v) std::cout << item << " ";
        std::cout << std::endl;
    }
    return 0;
}

4--组合总和III

主要思路:

        类似于上面的组合问题,基于回溯来暴力枚举每一个数,需要注意剪枝操作;

#include <iostream>
#include <vector>

class Solution {
public:
    std::vector<std::vector<int>> combinationSum3(int k, int n) {
        std::vector<int> path;
        backTracking(k, n, 0, path, 1);
        return res;
    }

    void backTracking(int k, int n, int sum, std::vector<int>path, int start){
        if(sum > n) return; // 剪枝
        if(path.size() == k){ // 递归终止
            if(sum == n){
                res.push_back(path);
            }
            return;
        }

        for(int i = start; i <= 9 + path.size() - k + 1; i++){ // 剪枝
            path.push_back(i);
            sum += i;
            backTracking(k, n, sum, path, i + 1); // 递归枚举下一个数
            // 回溯
            sum -= i;
            path.pop_back();
        }

    }
private:
    std::vector<std::vector<int>> res;
};

int main(int argc, char* argv[]){
    int k = 3, n = 7;
    Solution S1;
    std::vector<std::vector<int>> res = S1.combinationSum3(k, n);
    for(auto v : res){
        for(int item : v) std::cout << item << " ";
        std::cout << std::endl;
    }
    return 0;
}

5--电话号码的字母组合

主要思路:

        

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

异地远程访问内网BUG管理系统【Cpolar内网穿透】

文章目录 前言1. 本地安装配置BUG管理系统2. 内网穿透2.1 安装cpolar内网穿透2.2 创建隧道映射本地服务3. 测试公网远程访问4. 配置固定二级子域名4.1 保留一个二级子域名5.1 配置二级子域名6. 使用固定二级子域名远程 前言 BUG管理软件,作为软件测试工程师的必备工具之一。在…

前端组件库造轮子——Message组件开发教程

前端组件库造轮子——Message组件开发教程 前言 本系列旨在记录前端组件库开发经验&#xff0c;我们的组件库项目目前已在Github开源&#xff0c;下面是项目的部分组件。文章会详细介绍一些造组件库轮子的技巧并且最后会给出完整的演示demo。 文章旨在总结经验&#xff0c;开…

Linux修复软RAID

系统应该将mdadm配置成当发生RAID问题时给root用户发送邮件。需要更改/etc/mdadm/mdadm.xonf里的MALLADDR 并用/etc/init.d/mdadm reload重新加载下 查看/proc/mdstat文件 可以看到sdd1被标记F&#xff0c;说明它已经失效 从/dev/md0中移除磁盘sdd1 想要移除磁盘&#xff…

vmware workstation设置固定ip的几种方法

环境: keyvalue宿主机系统Windows11虚拟机系统Ubuntu20.04虚拟化软件vmware workstation 17 provmware workstation网络模式NAT 众所周知,vmware workstation在NAT模式下,会使用dhcp分配ip,每个ip的默认租约是半小时(1800s),最大租约时间也只有2小时(7200s),所以ip会频繁变动…

C++项目实战——基于多设计模式下的同步异步日志系统-①-项目介绍

文章目录 专栏导读项目介绍开发环境核心技术环境搭建日志系统介绍1.为什么需要日志系统2.日志系统技术实现2.1同步写日志2.2异步写日志 专栏导读 &#x1f338;作者简介&#xff1a;花想云 &#xff0c;在读本科生一枚&#xff0c;C/C领域新星创作者&#xff0c;新星计划导师&a…

mysql 锁解决的办法

可以查看锁的信息,TRX_MYSQL_THREAD_ID 为processlist的表中的会话id,用于kill select trx_id,trx_state,trx_started,trx_requested_lock_id,trx_wait_started,trx_weight,trx_mysql_thread_id,trx_query from innodb_trx 可以查看锁的模式&#xff0c;类型&#xff0c;锁的表…

安防视频监控/视频汇聚平台EasyCVR服务重启,海康SDK设备无法上线是什么原因?

TSINGSEE青犀视频监控汇聚平台EasyCVR可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。旭帆科技平台既具备传统安防视频监控…

Elasticsearch:利用向量搜索进行音乐信息检索

作者&#xff1a;Alex Salgado 欢迎来到音乐信息检索的未来&#xff0c;机器学习、向量数据库和音频数据分析融合在一起&#xff0c;带来令人兴奋的新可能性&#xff01; 如果你对音乐数据分析领域感兴趣&#xff0c;或者只是热衷于技术如何彻底改变音乐行业&#xff0c;那么本…

Pycharm创建项目时如何自动添加头部信息

1.打开PyCharm&#xff0c;选择File--Settings 2.依次选择Editor---Code Style-- File and Code Templates---Python Script 3..添加头部内容 可以根据需要添加相应的信息 #!/usr/bin/python3可用的预定义文件模板变量为&#xff1a;$ {PROJECT_NAME} - 当前项目的名称。$ {NAM…

基于减法优化SABO优化ELM(SABO-ELM)负荷预测(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

第4篇 vue的常用事件操作

一 vue常用操作案例 1.1 事件渲染 1.数据渲染的方式&#xff1a;使用插值表达式{{}}进行数据渲染 2.数据渲染的方式&#xff1a;以使用 v-bind指令&#xff0c;它的简写的形式就是一个冒号&#xff08;:&#xff09;&#xff0c;v-bind 特性被称为指令。指令带有前缀 v- 代…

Vscode中注释变成繁体的解决方法

前言 文章底部有个人公众号&#xff1a;热爱技术的小郑。主要分享开发知识、有兴趣的可以关注一下。为何分享&#xff1f; 踩过的坑没必要让别人在再踩&#xff0c;自己复盘也能加深记忆。利己利人、所谓双赢。 代码中的注释变成繁体字了、归根到底是由于字体的编码格式造成。前…

Java Properties类

使用SpringBoot框架时&#xff0c;会使用application.properties进行一些项目配置。 下面讲讲原理。 Properties是Map接口下面的一个实现类&#xff0c;所以Properties也是一种双列集合&#xff0c;用来存储键值对。但是一般不会把它当做集合来使用。当作属性文件来使用。 读…

2023年19款最佳3D打印软件

推荐&#xff1a;使用 NSDT场景编辑器 快速搭建3D应用场景 什么是好的3D打印软件&#xff1f; 虽然我们包括一系列非常不同的3D打印软件&#xff0c;旨在满足非常不同的需求&#xff0c;但有一些关键方面可以决定3D打印机软件的成败。 广泛的工具&#xff1a;我们选择了具有多…

如何使用聊天GPT自定义说明

推荐&#xff1a;使用 NSDT场景编辑器 快速搭建3D应用场景 OpenAI ChatGPT正在席卷全球。一周又一周&#xff0c;更新不断提高您可以使用这种最先进的语言模型做什么的标准。 在这里&#xff0c;我们深入研究了OpenAI最近在ChatGPT自定义指令上发布的公告。此功能最初以测试版…

Cesium之TerrainProvider地形数据获取

1. 挖方填方的案例中是用什么方法获取的地形数据&#xff1f; 是有官方的api接口一口气返回一个区域内的高程值吗 回答&#xff1a;读取渲染的地形瓦片的三角面。 2. 你们怎么通过高程点构建三角网的&#xff1f; 回答&#xff1a;读取地形瓦片的顶点和索引 3. 这个是有现…

C++ - 多态语法 - 虚函数使用介绍

多态简单介绍 多态就是多种形态&#xff0c;是不同的对象去完成同一个动作所产生的结果可能有多种。这种多种的形态我们称之为多态。 比如&#xff1a;我们在买票的时候的时候&#xff0c;可能有成人全价&#xff0c;儿童半价&#xff0c;军人免票等等。对于成人&#xff0c;儿…

北斗高精度组合导航终端

UWB&#xff08;Ultra-Wideband&#xff09;、卫星定位&#xff08;GNSS&#xff09;&#xff0c;以及IMU&#xff08;Inertial Measurement Unit&#xff09;的组合定位系统结合了多种传感器和定位技术&#xff0c;以提供高精度、高可靠性的位置估计。这种组合定位系统在各种应…

五种定时任务方案(Timer+ScheduleExecutorService+spring task+多线程执行+quartz)

方案一&#xff1a;Timer (1)Timer.schedule(TimerTask task,Date time)安排在制定的时间执行指定的任务。 (2)Timer.schedule(TimerTask task,Date firstTime ,long period)安排指定的任务在指定的时间开始进行重复的固定延迟执行&#xff0e; (3)Timer.schedule(TimerTask…

网络技术十五:DHCP

DHCP 引入原因&#xff08;产生背景&#xff09; 手动为局域网中大量主机配置IP地址、掩码、网关等参数的工作繁琐&#xff0c;容易出错 DHCP可以自动为局域网中主机完成TCP/IP协议配置 DHCP自动配置避免了IP地址冲突的问题 定义 动态主机配置协议 用于为局域网中主机动态分…