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

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--电话号码的字母组合

主要思路:

        根据传入的字符串,遍历每一个数字字符,基于回溯法,递归遍历每一个数字字符对应的字母;

#include <iostream>
#include <vector>
#include <string>class Solution {
public:std::vector<std::string> letterCombinations(std::string digits) {if(digits.length() == 0) return res;std::vector<std::string> letter = {"", " ", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};backTracking(digits, letter, 0);return res;}void backTracking(std::string digits, std::vector<std::string> letter, int cur){if(cur == digits.size()){res.push_back(tmp);return;}int letter_idx = digits[cur] - '0';int letter_size = letter[letter_idx].size();for(int i = 0; i < letter_size; i++){tmp.push_back(letter[letter_idx][i]);backTracking(digits, letter, cur+1);// 回溯tmp.pop_back();}}private:std::vector<std::string> res;std::string tmp;
};int main(int argc, char* argv[]){std::string test = "23";Solution S1;std::vector<std::string> res = S1.letterCombinations(test);for(std::string str : res) std::cout << str << " ";std::cout << std::endl;return 0;
}

6--组合总和

主要思路:

        经典组合问题,通过回溯法暴力递归遍历;

#include <iostream>
#include <vector>class Solution {
public:std::vector<std::vector<int>> combinationSum(std::vector<int>& candidates, int target) {if(candidates.size() == 0) return res;backTracking(candidates, target, 0, 0, path);return res;}void backTracking(std::vector<int>& candidates, int target, int sum, int start, std::vector<int>path){if(sum > target) return; // 剪枝if(sum == target) {res.push_back(path);return;}for(int i = start; i < candidates.size(); i++){sum += candidates[i];path.push_back(candidates[i]);backTracking(candidates, target, sum, i, path);// 回溯sum -= candidates[i];path.pop_back();}}private:std::vector<std::vector<int>> res;std::vector<int> path;
};int main(int argc, char* argv[]){// candidates = [2,3,6,7], target = 7std::vector<int> test = {2, 3, 6, 7};int target = 7;Solution S1;std::vector<std::vector<int>> res = S1.combinationSum(test, target);for(auto vec : res){for(int val : vec) std::cout << val << " ";std::cout << std::endl; }return 0;
}

7--组合总和II

主要思路:

        基于回溯法,暴力递归遍历数组;

        本题不能包含重复的组合,但由于有重复的数字,因此需要进行树层上的去重

#include <iostream>
#include <vector>
#include <algorithm>class Solution {
public:std::vector<std::vector<int>> combinationSum2(std::vector<int>& candidates, int target) {if(candidates.size() == 0) return res;std::sort(candidates.begin(), candidates.end());std::vector<bool> visited(candidates.size(), false);backTracking(candidates, target, 0, 0, visited);return res;}void backTracking(std::vector<int>& candidates, int target, int sum, int start, std::vector<bool>& visited){if(sum > target) return; // 剪枝if(sum == target){res.push_back(path);return;}for(int i = start; i < candidates.size(); i++){// 树层剪枝去重if(i > 0 && candidates[i-1] == candidates[i]){if(visited[i-1] == false) continue;}sum += candidates[i];path.push_back(candidates[i]);visited[i] = true;backTracking(candidates, target, sum, i+1, visited);// 回溯sum -= candidates[i];path.pop_back();visited[i] = false;}}private:std::vector<std::vector<int>> res;std::vector<int> path;
};int main(int argc, char* argv[]){// candidates = [10,1,2,7,6,1,5], target = 8std::vector<int> test = {10, 1, 2, 7, 6, 1, 5};int target = 8;Solution S1;std::vector<std::vector<int>> res = S1.combinationSum2(test, target);for(auto vec : res){for(int val : vec) std::cout << val << " ";std::cout << std::endl; }return 0;
}

8--

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

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

相关文章

K8S 基础概念学习

1.K8S 通过Deployment 实现滚动发布&#xff0c;比如左边的ReplicatSet 的 pod 中 是V1版本的镜像&#xff0c;Deployment通过 再启动一个 ReplicatSet 中启动 pod中 镜像就是V2 2.每个pod 中都有一个pause 容器&#xff0c;他会连接本pod中的其他容器&#xff0c;实现互通。p…

【Java】基于SSM的单位人事管理系统

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

[Linux]动静态库

[Linux]动静态库 文章目录 [Linux]动静态库见一见库存在库的原因编写库模拟编写静态库模拟使用静态库模拟编写动态库模拟使用静态库 库的加载原理静态库的加载原理动态库的加载原理 库在可执行程序中的编址策略静态库在可执行程序中的编址策略动态库在可执行程序中的编址策略 见…

储能直流侧计量表DJSF1352

安科瑞 华楠 具有CE/UL/CPA/TUV认证 DJSF1352-RN导轨式直流电能表带有双路直流输入&#xff0c;主要针对电信基站、直流充电桩、太阳能光伏等应用场合而设计&#xff0c;该系列仪表可测量直流系统中的电压、电流、功率以及正反向电能等。在实际使用现场&#xff0c;即可计量总…

LT8711HE 是一款高性能的Type-C/DP1.2到HDMI2.0转换器

概述&#xff1a; LT8711HE是一种高性能的Type-C/DP1.2到HDMI2.0转换器&#xff0c;设计用于连接USB Type-C源或DP1.2源到HDMI2.0接收器。LT8711HE集成了一个DP1.2兼容的接收器&#xff0c;和一个HDMI2.0兼容的发射机。此外&#xff0c;还包括两个CC控制器&#xff0c;用于CC通…

自然语言处理——数据清洗

一、什么是数据清洗 数据清洗是指发现并纠正数据文件中可识别的错误的最后一道程序&#xff0c;包括检查数据一致性&#xff0c;处理无效值和缺失值等。与问卷审核不同&#xff0c;录入后的数据清理一般是由计算机而不是人工完成。 ——百度百科 二、为什么要数据清洗 现实生…

bboss 流批一体化框架 与 数据采集 ETL

数据采集 ETL 与 流批一体化框架 特性&#xff1a; 高效、稳定、快速、安全 bboss 是一个基于开源协议 Apache License 发布的开源项目&#xff0c;主要由以下三部分构成&#xff1a; Elasticsearch Highlevel Java Restclient &#xff0c; 一个高性能高兼容性的Elasticsea…

java开发之个人微信的二次开发

简要描述&#xff1a; 修改我在某群的昵称 请求URL&#xff1a; http://域名/updateIInChatRoomNickName 请求方式&#xff1a; POST 请求头Headers&#xff1a; Content-Type&#xff1a;application/jsonAuthorization&#xff1a;login接口返回 参数&#xff1a; 参…

Python标准数据类型-List(列表)

✅作者简介&#xff1a;CSDN内容合伙人、阿里云专家博主、51CTO专家博主、新星计划第三季python赛道Top1&#x1f3c6; &#x1f4c3;个人主页&#xff1a;hacker707的csdn博客 &#x1f525;系列专栏&#xff1a;零基础入门篇 &#x1f4ac;个人格言&#xff1a;不断的翻越一座…

备份StarRocks数据到对象存储minio中/外表查minio中的数据

1.部署minio环境 docker pull minio/minio宿主机与容器挂在映射 宿主机位置容器位置/data/minio/config/data/data/minio/data/root/.minio 拉起环境&#xff1a; docker run -p 9000:9000 -p 9090:9090 --name minio \ -d --restartalways \ -e "MINIO_ACCESS_KEYadm…

基于Dubbo实现服务的远程调用

目录 前言 RPC思想 为什么使用Dubbo Dubbo技术框架 ​编辑 调用关系流程 基础实现 A.提供统一业务Api B.编辑服务提供者Product B.a 添加依赖 B.b 添加Dubbo 配置(基于yaml配置文件) B.c 编写并暴露服务 C.编辑服务消费者 C.a 添加依赖 C.b 添加Dubbo配置 C.c 引用…

使用正则表达式总结

多行匹配 使用Pattern.DOTALL | Pattern.MULTILINE参数 Pattern.CASE_INSENSITIVE&#xff1a;不区分大小写 public static void main(String[] args) {String teststr "AA aa AASSF \n\r */ DDET AA";String regStr "(?AA)\\w\\b";extracted(testst…

网络威胁防御+资产测绘系统-Golang开发

NIPS-Plus 网络威胁防御资产测绘系统-Golang开发 项目地址&#xff1a;https://github.com/jumppppp/NIPS-Plus NIPS-Plus 是一款使用golang语言开发的网络威胁防御系统&#xff08;内置资产测绘系统&#xff09; 网络威胁流量视图网络威胁详细信息浏览列表网络威胁反制探测攻…

C++ std::pair and std::list \ std::array

std::pair<第一个数据类型, 第二个数据类型> 变量名 例如&#xff1a; std::pair<int, string> myPair; myPair.first;拿到第一个int变量 myPair.second拿到第二个string变量 std::pair需要引入库#include "utility" std::make_pair() 功能制作一个…

数控程序传输DNC服务、数控刀补服务(发那科fanuc、西门子、三菱、广数、新代、华中、宝元、马扎克、大畏Okuma)等数据采集服务

行业现状&#xff1a; 最近听到很多做MES、ERP这一行的叫苦&#xff0c; 客户对项目的要求越来越严格&#xff0c;做到数字化工厂都伴随着ERP、MES的项目要求必须一起做下去 然而很对MES、ERP对设备协议不懂&#xff0c;买了协议自己还要开发&#xff0c;考虑线程的问题、断…

syn洪流原理

TCP三次握手 建立连接发送或回应第一次握手客户端发送报文&#xff0c;标志位为SYN&#xff08;seqa&#xff09;第二次握手服务器发送报文&#xff0c;标志位为SYN&#xff0c;ACK&#xff08;seqb,acka1&#xff09;第三次握手客户端回应服务器报文&#xff0c;标志位为ACK&…

Unity 之 Invoke 与InvokeRepeting 函数控制定时调用

文章目录 InvokeInvokeRepeating Invoke 在Unity游戏开发中&#xff0c;Invoke是一种用于延迟调用方法的方法。它允许你在一定的时间之后执行特定的函数或方法&#xff0c;通常用于执行定时任务&#xff0c;例如在一段时间后触发一个事件或在一定间隔内重复执行某个方法。Invo…

图的应用(最小生成树,最短路径,有向无环图)

目录 一.最小生成树 1.生成树 2.无向图的生成树 3.最小生成树算法 二.最短路径 1.单源最短路径---Dijkstra&#xff08;迪杰斯特拉&#xff09;算法 2.所有顶点间的最短路径---Floyd&#xff08;弗洛伊德&#xff09;算法 三.有向无环图的应用 1.AOV网&#xff08;拓扑…

Opencv手工选择图片区域去水印

QT 插件化图像算法研究平台的功能在持续完善&#xff0c;补充了一个人工选择图片区域的功能。 其中&#xff0c;图片选择功能主要代码如下&#xff1a; QRect GLImageWidget::getSeleted() {QRect ajust(0,0,0,0);if(image.isNull() || !hasSelection)return ajust;double w1…

智能小车之测速小车原理和开发

目录 1. 测速模块介绍 2. 测试原理和单位换算 3. 定时器和中断实现测速开发和调试代码 4. 小车速度显示在OLED屏 1. 测速模块介绍 用途&#xff1a;广泛用于电机转速检测&#xff0c;脉冲计数,位置限位等。有遮挡&#xff0c;输出高电平&#xff1b;无遮挡&#xff0c;输出…