重拾C++之菜鸟刷算法第11篇---回溯算法(上)

2024-03-12 02:28
文章标签 算法 c++ 重拾 回溯 菜鸟

本文主要是介绍重拾C++之菜鸟刷算法第11篇---回溯算法(上),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

今天是个好日子,二月二龙抬头,龙年龙日龙抬头,顺风顺水好兆头,万事万物开好头,金银珠宝往家里走!offer往家走!

回溯算法

回溯法可以解决的问题

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

回溯三部曲

  1. 回溯函数模板返回值以及参数
  2. 回溯函数终止条件
  3. 回溯搜索的遍历过程
void backtracking(参数){if(终止条件){存放结果;return;}for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)){backtracking(路径,选择列表); // 递归回溯,撤销处理结果}}

组合

for循环横向遍历,递归纵向遍历,回溯不断调整结果集

题目

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

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

77. 组合 - 力扣(LeetCode)

题解

class Solution {
public:// 创建一个全局变量来放pathvector<int> path;// 创建一个全局变量来放所有的pathvector<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;}
};

可以剪枝的地方在递归中每一层的for循环所选择的位置,比如说for循环选择的起始位置之后的元素个数已不足k个,那么就没有必要再进行for循环

组合总和III

题目

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

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

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

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

题解

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

电话号码的字母组合

题目

给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。

给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。

17. 电话号码的字母组合 - 力扣(LeetCode)

题解

index:是记录遍历第几个数字了,就是用来遍历digits的(题目中给出数字字符串),同时index也表示树的深度。

class Solution {
public:vector<string> result;string path;void backtracking(const string &digits, int index){if(index == digits.size()){result.push_back(path);return;}int digit = digits[index] - '0';string letters = letterMap[digit];for(int i = 0; i < letters.size(); i++){path.push_back(letters[i]);backtracking(digits, index + 1);path.pop_back();}}vector<string> letterCombinations(string digits) {if(digits.size() == 0) return result;backtracking(digits, 0);return result;}
private:const string letterMap[10] = {"", //0"", //1"abc", //2"def", //3"ghi", //4"jkl", //5"mno", //6"pqrs", //7"tuv", //8"wxyz", // 9};
};

这篇关于重拾C++之菜鸟刷算法第11篇---回溯算法(上)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/799854

相关文章

Java中的雪花算法Snowflake解析与实践技巧

《Java中的雪花算法Snowflake解析与实践技巧》本文解析了雪花算法的原理、Java实现及生产实践,涵盖ID结构、位运算技巧、时钟回拨处理、WorkerId分配等关键点,并探讨了百度UidGen... 目录一、雪花算法核心原理1.1 算法起源1.2 ID结构详解1.3 核心特性二、Java实现解析2.

从入门到精通C++11 <chrono> 库特性

《从入门到精通C++11<chrono>库特性》chrono库是C++11中一个非常强大和实用的库,它为时间处理提供了丰富的功能和类型安全的接口,通过本文的介绍,我们了解了chrono库的基本概念... 目录一、引言1.1 为什么需要<chrono>库1.2<chrono>库的基本概念二、时间段(Durat

C++20管道运算符的实现示例

《C++20管道运算符的实现示例》本文简要介绍C++20管道运算符的使用与实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录标准库的管道运算符使用自己实现类似的管道运算符我们不打算介绍太多,因为它实际属于c++20最为重要的

Visual Studio 2022 编译C++20代码的图文步骤

《VisualStudio2022编译C++20代码的图文步骤》在VisualStudio中启用C++20import功能,需设置语言标准为ISOC++20,开启扫描源查找模块依赖及实验性标... 默认创建Visual Studio桌面控制台项目代码包含C++20的import方法。右键项目的属性:

c++中的set容器介绍及操作大全

《c++中的set容器介绍及操作大全》:本文主要介绍c++中的set容器介绍及操作大全,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录​​一、核心特性​​️ ​​二、基本操作​​​​1. 初始化与赋值​​​​2. 增删查操作​​​​3. 遍历方

解析C++11 static_assert及与Boost库的关联从入门到精通

《解析C++11static_assert及与Boost库的关联从入门到精通》static_assert是C++中强大的编译时验证工具,它能够在编译阶段拦截不符合预期的类型或值,增强代码的健壮性,通... 目录一、背景知识:传统断言方法的局限性1.1 assert宏1.2 #error指令1.3 第三方解决

C++11委托构造函数和继承构造函数的实现

《C++11委托构造函数和继承构造函数的实现》C++引入了委托构造函数和继承构造函数这两个重要的特性,本文主要介绍了C++11委托构造函数和继承构造函数的实现,具有一定的参考价值,感兴趣的可以了解一下... 目录引言一、委托构造函数1.1 委托构造函数的定义与作用1.2 委托构造函数的语法1.3 委托构造函

C++11作用域枚举(Scoped Enums)的实现示例

《C++11作用域枚举(ScopedEnums)的实现示例》枚举类型是一种非常实用的工具,C++11标准引入了作用域枚举,也称为强类型枚举,本文主要介绍了C++11作用域枚举(ScopedEnums... 目录一、引言二、传统枚举类型的局限性2.1 命名空间污染2.2 整型提升问题2.3 类型转换问题三、C

C++链表的虚拟头节点实现细节及注意事项

《C++链表的虚拟头节点实现细节及注意事项》虚拟头节点是链表操作中极为实用的设计技巧,它通过在链表真实头部前添加一个特殊节点,有效简化边界条件处理,:本文主要介绍C++链表的虚拟头节点实现细节及注... 目录C++链表虚拟头节点(Dummy Head)一、虚拟头节点的本质与核心作用1. 定义2. 核心价值二

C++ 检测文件大小和文件传输的方法示例详解

《C++检测文件大小和文件传输的方法示例详解》文章介绍了在C/C++中获取文件大小的三种方法,推荐使用stat()函数,并详细说明了如何设计一次性发送压缩包的结构体及传输流程,包含CRC校验和自动解... 目录检测文件的大小✅ 方法一:使用 stat() 函数(推荐)✅ 用法示例:✅ 方法二:使用 fsee