面试热点题:回溯算法之组合 组合与组合总和 III
什么是回溯算法?
回溯算法也可以叫回溯搜索算法,回溯是递归的"副产品",回溯的本质是穷举,然后选出我们需要的数据,回溯本身不是特别高效的算法,但我们可以通过"剪枝"来优化它。
理解回溯算法
回溯算法的解决可以模拟成树的结构,因为回溯法解决的是在集合中递归搜索子集的过程,集合的大小构成树的宽度,递归的深度构成树的深度。
回溯算法模板
- 确定回溯算法的返回值与参数(一般先写逻辑,然后需要什么参数,就增加什么参数)
- 确定回溯函数的终止条件
- 确定回溯搜查的遍历过程
void BackTracking(参数)
{if (终止条件){处理结果return;}for (选择:本层集合中的元素(树中节点孩子的数量就是集合的大小)){处理节点BackTracking(路径,选择列表);//递归回溯,撤销处理结果}
}
组合
问题:
给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 k 个数的组合。
你可以按 任何顺序 返回答案。
来源:力扣(LeetCode)组合

思路一:这种题目我们一眼就能想到使用for循环套循环比如 k==2时
int n = 4;for (int i = 1; i <= n; i++){for (int j = i + 1; j <= n; j++){//处理结果}}
但是如果k越来越大,我们套用的循环也会越来越多,这种暴力解法无疑是不现实的。
思路二:我们在前面说过,可以使用树的结构来模拟回溯递归的过程:
比如n=4 k=2

树的初始集合是[1,2,3,4],从左向右取,取过的数不再取,每次从集合中选取元素,可选择的范围逐渐缩小。有图可以发现,n相当于树的宽度,而k相当于树的深度。我们再由模板来写出最终代码:
class Solution {
public:vector<vector<int>> arr;//存放符合条件的集合vector<int> _arr;//用来存放符合条件的单一数据void BackTracking(int n, int k, int begin){if (_arr.size() == k)//递归终止条件{arr.push_back(_arr);//单一数据存放至总集合里return;}for (int i = begin; i <= n; i++)//控制树的横向遍历{_arr.push_back(i);//处理节点BackTracking(n, k, i + 1);//递归,控制树的纵向遍历,即深度_arr.pop_back();//回溯,撤销处理的节点}}vector<vector<int>> combine(int n, int k) {BackTracking(n, k, 1);return arr;}
};
剪枝优化
如果出现下面情况:
n=4 k=4
那么在第一层for循环中,从元素2开始的遍历都没有意义,因为满足k的数量不够了,所以有图可知,打叉的地方都可以优化掉

优化过程:
- 已经选择的元素个数:_arr.size()
- 还需要的元素个数:k - _arr.size()
优化后的代码:
class Solution {
public:vector<int> _arr;vector<vector<int>> arr;void BackTracking(int n, int k, int begin){if (_arr.size() == k){arr.push_back(_arr);return;}for (int i = begin; i <= n-(k-_arr.size())+1; i++)//剪枝优化{_arr.push_back(i);BackTracking(n, k, i + 1);_arr.pop_back();}}vector<vector<int>> combine(int n, int k) {BackTracking(n, k, 1);return arr;}
};
组合总和 III
问题:
找出所有相加之和为 n 的 k 个数的组合,且满足下列条件:
- 只使用数字1到9
- 每个数字 最多使用一次
返回 所有可能的有效组合的列表 。该列表不能包含相同的组合两次,组合可以以任何顺序返回。
来源:力扣(LeetCode)组合总和 III

思路:这个题相对于上一个题来说,就是k为树的深度,而集合固定为1到9,也就是树的宽度为9
比如:k=2 只取两个数

代码:
class Solution {
public:vector<vector<int>> arr;vector<int> _arr;void BackTracking(int k,int n,int begin,int sum){if(_arr.size()==k)//终止条件{if(sum==n)//满足题意{arr.push_back(_arr);}return;}for(int i=begin;i<=9;i++)//横向遍历{sum+=i;//收集元素总和_arr.push_back(i);//收集元素BackTracking(k,n,i+1,sum);//递归,纵向遍历sum-=i;//回溯_arr.pop_back();//回溯}}vector<vector<int>> combinationSum3(int k, int n) {BackTracking(k,n,1,0);return arr;}
};
剪枝优化
如果我们选择的元素总和已经大于n,那么我们再往后遍历的总和肯定也大于n,就没有继续遍历下去的意义了。元素个数方面,同样与上一题一样能继续优化。

优化后:
class Solution {
public:vector<vector<int>> arr;vector<int> _arr;void BackTracking(int k,int n,int begin,int sum){if(sum>n)//剪枝条件{return;}if(_arr.size()==k){if(sum==n){arr.push_back(_arr);}return;}for(int i=begin;i<=9-(k-_arr.size())+1;i++)//元素个数的优化{sum+=i;_arr.push_back(i);BackTracking(k,n,i+1,sum);sum-=i;_arr.pop_back();}}vector<vector<int>> combinationSum3(int k, int n) {BackTracking(k,n,1,0);return arr;}
};
相关文章:
面试热点题:回溯算法之组合 组合与组合总和 III
什么是回溯算法? 回溯算法也可以叫回溯搜索算法,回溯是递归的"副产品",回溯的本质是穷举,然后选出我们需要的数据,回溯本身不是特别高效的算法,但我们可以通过"剪枝"来优化它。 理解回溯算法 回溯…...
java面试-jvm
JVM JVM 是 java 虚拟机,简单来说就是能执行标准 java 字节码的虚拟计算机 JVM 是如何工作的 首先程序在执行之前先要把 Java 代码(.java)转换成字节码(.class),JVM 通过类加载器(ClassLoade…...
vscode下载与使用
1.vscode下载 官网下载地址:Download Visual Studio Code - Mac, Linux, Windows下载太慢,推荐文章:解决VsCode下载慢问题_vscode下载太慢_迷小圈的博客-CSDN博客下载太慢,推荐下载链接:https://vscode.cdn.azure.cn/s…...
人员摔倒识别预警算法 opencv
人员摔倒识别预警算法通过opencv网络模型技术,人员摔倒识别预警算法能够智能检测现场画面中人员有没有摔倒,无需人为干预可以立刻抓拍告警。OpenCV的全称是Open Source Computer Vision Library,是一个跨平台的计算机视觉处理开源软件库&…...
华为OD机试题 - 火星文计算(JavaScript)| 机考必刷
更多题库,搜索引擎搜 梦想橡皮擦华为OD 👑👑👑 更多华为OD题库,搜 梦想橡皮擦 华为OD 👑👑👑 更多华为机考题库,搜 梦想橡皮擦华为OD 👑👑👑 华为OD机试题 最近更新的博客使用说明本篇题解:火星文计算题目输入输出示例一输入输出说明Code解题思路版权说明…...
AI人工智能 - 初探
1.应用场景 主要用于了解和系统学习AI,从而可以在工作生活中利用AI做一些事。 2.学习/操作 1.文档阅读 下面的内容来自于与chatGPT的对话 2.整理输出 介绍AI 人工智能(Artificial Intelligence,简称AI)是计算机科学中的一个分支&…...
Spring-AOP工作流程
Spring-AOP工作流程 3,AOP工作流程 3.1 AOP工作流程 由于AOP是基于Spring容器管理的bean做的增强,所以整个工作过程需要从Spring加载bean说起: 流程1:Spring容器启动 容器启动就需要去加载bean,哪些类需要被加载呢?需要被增强的类,如:B…...
C51---串口发送指令,控制LED灯亮灭
1.Code: #include "reg52.h" #include "intrins.h" sfr AUXR 0x8E; sbit D5 P3^7; void UartInit(void) //9600bps11.0592MHz { //PCON & 0x7F; //波特率不倍速 AUXR 0x01; SCON 0x50; //8位数据,可变波…...
【Wiki】XWiki数据备份
XWiki为主题使用java开发的开源wiki,官网地址如下: https://www.xwiki.org/xwiki/bin/view/Main/ 目录1、 XWiki升级数据备份1.1、 获取XWiki配置的数据库与持久化目录信息1.2 备份数据库信息1.3 备份持久化目录2、XWiki数据迁移如果一个知识库不能确保数…...
ctk框架开发Qt插件应用示例工程
目录 前言 约定 插件工程pluginApp: 主启动工程StartApp: 效果演示 结语...
spring5源码篇(4)——beanFactoryPostProcessor执行/注解bean的装配
spring-framework 版本:v5.3.19 前面研究了beanDefinition的注册,但也仅仅是注册这一动作。那么在spring容器启动的过程中,是何时/如何装配的?以及装配的bean是如何注入的? (考虑到xml方式基本不用了以及篇…...
masstransit的message几个高级用法
1)问题,Class MessageA 基类,Class MessageB继承自MessageA; 用bus.Publish方法本想把有些消息只发给B队列,结果由于其继承关系A队列也获得了消息; 解决方法用send, Uri uri new Uri(RabbitM…...
漏洞分析丨cve-2012-0003
作者:黑蛋一、漏洞简介这次漏洞属于堆溢出漏洞,他是MIDI文件中存在的堆溢出漏洞。在IE6,IE7,IE8中都存在这个漏洞。而这个漏洞是Winmm.dll中产生的。二、漏洞环境虚拟机调试工具目标软件辅助工具XP-SP3、KaliOD、IDAIE6Windbg组件gflags.exe三…...
rm命令——删除文件或目录
rm命令是英文单词remove的缩写,主要功能是删除文件或目录。 因为删除文件是一个破坏性动作,因此,在使用时需要格外小心,在执行之前一定要再三确认删除的是哪个目录中的什么文件。 rm命令的语法格式如下: rm [选项] …...
【零基础入门学习Python---Python的基本语法使用】
一.Python基本语法使用 Python是一种易学且功能强大的编程语言,具有简洁的语法和广泛的应用领域。在本文中,我们将介绍Python的基本语法使用,以帮助初学者快速入门Python编程。 1.1 注释 Python 支持两种类型的注释:单行注释和多行注释。 单行注释:以 # 符号开头,从 # …...
数据仓库相关概念的解释
数据仓库相关概念的解释 文章目录数据仓库相关概念的解释1 ETL是什么?ETL体系结构2 数据流向何为数仓DW3 ODS 是什么?4 数据仓库层DWDWD 明细层DWD 轻度汇总层(MID或DWB,data warehouse basis)DWS 主题层(D…...
1/4车、1/2车、整车悬架模糊PID控制仿真合集
目录 前言 1. 1/4悬架系统 1.1数学模型 1.2仿真分析 2. 1/2悬架系统 2.1数学模型 2.2仿真模型 2.3仿真分析 3. 整车悬架系统 3.1数学模型 3.2仿真分析 4.总结 前言 前面几篇文章介绍了LQR、SkyHook、H2/H∞、PID控制,接下来会继续介绍滑模、反步法、M…...
Linux性能补丁升级,避免不必要的跨核Wake-Up
导读一个由英特尔发起的、旨在改进Linux内核公平调度程序代码的补丁系列,也看到了来自AMD工程师和其他利益相关者的测试/反馈,并继续进行改进。这个补丁系列的重点是避免在不必要的情况下发生过多的跨核唤醒(Cross-CPU Wake-up)。这样一来,这…...
Spring Cloud Alibaba全家桶(六)——微服务组件Sentinel介绍与使用
前言 本文小新为大家带来 微服务组件Sentinel介绍与使用 相关知识,具体内容包括分布式系统存在的问题,分布式系统问题的解决方案,Sentinel介绍,Sentinel快速开始(包括:API实现Sentinel资源保护,…...
拼多多2021笔试真题集 -- 3. 多多的求和计算
多多的求和计算 多多路上从左到右有N棵树(编号1~N),其中第i个颗树有和谐值Ai。 多多鸡认为,如果一段连续的树,它们的和谐值之和可以被M整除,那么这个区间整体看起来就是和谐的。 现在多多鸡想请…...
云计算——弹性云计算器(ECS)
弹性云服务器:ECS 概述 云计算重构了ICT系统,云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台,包含如下主要概念。 ECS(Elastic Cloud Server):即弹性云服务器,是云计算…...
使用 SymPy 进行向量和矩阵的高级操作
在科学计算和工程领域,向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能,能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作,并通过具体…...
Springboot社区养老保险系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,社区养老保险系统小程序被用户普遍使用,为方…...
【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论
路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中(图1): mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...
Linux中《基础IO》详细介绍
目录 理解"文件"狭义理解广义理解文件操作的归类认知系统角度文件类别 回顾C文件接口打开文件写文件读文件稍作修改,实现简单cat命令 输出信息到显示器,你有哪些方法stdin & stdout & stderr打开文件的方式 系统⽂件I/O⼀种传递标志位…...
向量几何的二元性:叉乘模长与内积投影的深层联系
在数学与物理的空间世界中,向量运算构成了理解几何结构的基石。叉乘(外积)与点积(内积)作为向量代数的两大支柱,表面上呈现出截然不同的几何意义与代数形式,却在深层次上揭示了向量间相互作用的…...
麒麟系统使用-进行.NET开发
文章目录 前言一、搭建dotnet环境1.获取相关资源2.配置dotnet 二、使用dotnet三、其他说明总结 前言 麒麟系统的内核是基于linux的,如果需要进行.NET开发,则需要安装特定的应用。由于NET Framework 是仅适用于 Windows 版本的 .NET,所以要进…...
写一个shell脚本,把局域网内,把能ping通的IP和不能ping通的IP分类,并保存到两个文本文件里
写一个shell脚本,把局域网内,把能ping通的IP和不能ping通的IP分类,并保存到两个文本文件里 脚本1 #!/bin/bash #定义变量 ip10.1.1 #循环去ping主机的IP for ((i1;i<10;i)) doping -c1 $ip.$i &>/dev/null[ $? -eq 0 ] &&am…...
【大厂机试题解法笔记】矩阵匹配
题目 从一个 N * M(N ≤ M)的矩阵中选出 N 个数,任意两个数字不能在同一行或同一列,求选出来的 N 个数中第 K 大的数字的最小值是多少。 输入描述 输入矩阵要求:1 ≤ K ≤ N ≤ M ≤ 150 输入格式 N M K N*M矩阵 输…...
生产管理系统开发:专业软件开发公司的实践与思考
生产管理系统开发的关键点 在当前制造业智能化升级的转型背景下,生产管理系统开发正逐步成为企业优化生产流程的重要技术手段。不同行业、不同规模的企业在推进生产管理数字化转型过程中,面临的挑战存在显著差异。本文结合具体实践案例,分析…...
