回溯算法之组合和排列问题
文章目录
- 1.什么是回溯算法
- 2.回溯算法解题步骤
- 3.回溯算法解决组合问题
- 4.回溯算法解决排列问题
1.什么是回溯算法
回溯算法是一种通过尝试所有可能的解决方案来解决问题的算法策略,它通常用于求解组合优化、排列组合、路径搜索等类型的问题,是一种暴力求解的算法。
2.回溯算法解题步骤
回溯算法是一种选优搜索法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为 “回溯点”。
回溯算法的解题步骤如下:
- 路径:记录已经做过的选择。
- 选择列表:当前可以做出的选择。
- 结束条件:到达决策树的底层,无法再做选择的条件。
回溯算法中最经典的就是组合和排列问题。
3.回溯算法解决组合问题
组合的定义
从 n 个不同元素中取出 m个元素组成一组,
不考虑元素的顺序,这样的一组元素就叫做从 n 个不同元素中取出 m 个元素的一个组合。
题目来自于https://leetcode.cn/problems/combinations/description/
题目描述:
给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 k 个数的组合。
你可以按 任何顺序 返回答案。
示例1:
输入:n = 4, k = 2
输出:
[
[2,4],
[3,4],
[2,3],
[1,2],
[1,3],
[1,4],
]
示例 2:
输入:n = 1, k = 1
输出:[[1]]
画图分析:
图为示例 1的情况下,当n = 4,k=2时,我们需要在[1,4]之间取出两个数组合:

用暴力求解的思想,我们很容易想到可以用两成for循环去做,但这题的n和k是动态的,想要控制好循环的层数,还是挺难的。
这个时候就需要使用到回溯算法了,先来看以下代码:
class Solution {public List<List<Integer>> result = new ArrayList<>();public List<Integer> path = new ArrayList<>();public List<List<Integer>> combine(int n, int k) {backTracking(n,k,1);return result;}public void backTracking(int n,int k,int startIndex){if(path.size() == k){result.add(new ArrayList<>(path));return;}for(int i = startIndex;i <= n-(k-path.size())+1;i++){path.add(i);backTracking(n,k,i+1);path.removeLast();}}
}
图解上述代码流程:

- result:用于存储最终的所有组合结果,是一个二维列表,每个子列表代表一个组合。
- path:用于存储路径上的值。
在循环过程中
- 首先将当前数字 i 添加到 path 中。
- 递归调用 backTracking 方法,继续生成下一个数字的组合,起始索引更新为 i + 1。
- 满足终止条件就收集数据,返回到上一次递归中进行回溯。
- 回溯操作,将最后添加的数字从 path 中移除,以便尝试其他可能的组合。
循环条件中的i <= n-(k-path.size())+1是为了剪枝。
来看一种极端情况,假设n = 4,k =4.

那么除了一开始的[1,2,3,4]其它情况都没必要遍历。在添加i <= n-(k-path.size())+1这个条件后,刚开始执行backTracking,我们就保证了i是小于等于1的,比1大的情况,组合的结果个数都小于4。
4.回溯算法解决排列问题
排列定义:
从 n 个不同元素中取出 m 个元素,
按照一定的顺序排成一列,叫做从 n 个不同元素中取出 m 个元素的一个排列。当 n =m 时,称为全排列。
题目来自:https://leetcode.cn/problems/permutations/description/
给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。
示例1:
输入:nums = [1,2,3]
输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
示例2:
输入:nums = [0,1]
输出:[[0,1],[1,0]]
示例3:
输入:nums = [1]
输出:[[1]]
以示例1来分析:

这一题其实和第一题类似,上一题的for循环要从当前位置的下一个位置开始,而这一题需要从头开始遍历,并且不能等于当前的值。
代码如下所示:
class Solution {public List<List<Integer>> result = new ArrayList<>();public ArrayList<Integer> path = new ArrayList<>();public List<List<Integer>> permute(int[] nums) {backTracking(nums);return result;}public void backTracking(int[] num){if(path.size() == num.length){result.add(new ArrayList<>(path));return;}for(int i = 0;i < num.length;i++){if(path.contains(num[i])){continue;}path.add(num[i]);backTracking(num);path.remove(path.size()-1);}}
}
只需要更改终止条件,并且在for循环中跳过path中包括的值即可。
相关文章:
回溯算法之组合和排列问题
文章目录 1.什么是回溯算法2.回溯算法解题步骤3.回溯算法解决组合问题4.回溯算法解决排列问题 1.什么是回溯算法 回溯算法是一种通过尝试所有可能的解决方案来解决问题的算法策略,它通常用于求解组合优化、排列组合、路径搜索等类型的问题,是一种暴力求解的算法。 2…...
gihub上适合练手的Python项目
GitHub 上有许多适合练手的 Python 项目,涵盖了从初学者到中级开发者的不同难度级别。以下是一些推荐的项目类型和具体示例,帮助你提升 Python 编程技能: 1. 基础项目 适合初学者,帮助掌握 Python 基础语法和常用库。 示例项目&…...
解锁CSnakes:.NET与Python的融合魔法
一、引言 在软件开发的广袤领域中,我们常常面临各种复杂的业务需求和技术挑战。不同的编程语言犹如各具特色的工具,它们在不同的场景下展现出独特的优势。例如,C# 以其强大的类型系统和丰富的类库,在企业级应用开发中占据重要地位…...
Python常见面试题的详解16
1. 如何强行关闭客户端和服务器之间的连接? 在网络编程中,有时需要强行中断客户端和服务器之间的连接。对于基于 TCP 协议的连接,由于其面向连接的特性,需要采取特定的步骤来确保连接被正确关闭;而 UDP 是无连接协议&a…...
建筑兔零基础自学python记录29|实战词云可视化项目——分人物阵营词云(上)7
我们在上次情感分析的基础上,不分积极消极,按文本中人物的阵营分为3队。可以猜想按照积极消极分类是有现成的feeling可以分析,但人物阵营却是没有现成资料,需要额外给出信息的。 图1 图2 上面两图的文字大小和数量有区别…...
Vi 编辑器基本使用指南
一、Vi 编辑器的启动与退出 启动 Vi 编辑器 在终端中,输入vi加上要编辑的文件名,如vi example.txt,如果example.txt存在,Vi 编辑器会打开该文件;若不存在,则会创建一个新的空文件并打开。如果只输入vi&am…...
22、《Spring Boot消息队列:RabbitMQ延迟队列与死信队列深度解析》
Spring Boot消息队列实战:RabbitMQ延迟队列与死信队列深度解析 引言 在现代分布式系统中,消息队列承担着解耦、削峰填谷和异步通信的重要职责。本文将深入探讨Spring Boot与RabbitMQ的整合应用,重点解析延迟队列与死信队列的实现原理及实战…...
linux 命令+相关配置记录(持续更新...)
linux 命令记录相关配置记录 磁盘切换 cd D:#这里表示切换到D盘查看wsl 安装的linux 子系统 wsl --list -vwsl 卸载 linux 子系统 wsl --unregister -xxx # xxx 表示子系统的名字备份Linux 子系统 导出 wsl --export xxx yyy # xxx 表示子系统的名字 yyy 表示压…...
ssh工具
文章目录 ssh简介ssh远程连接Linux下使用SSH安装安装ssh服务端安装ssh客户端 命令启动重启查看ssh的状态 ssh 配置文件ssh连接地址 配置文件基本配置注意通配符心跳和密钥ssh的Include跳板 ProxyJump内网穿透 Windows下使用SSH安装ssh 配置文件ssh连接地址 配置文件 ssh简介 s…...
LLM大语言模型私有化部署-使用Dify的工作流编排打造专属AI诗词数据分析师
背景 前面的文章通过 Ollama 私有化部署了 Qwen2.5 (7B) 模型,然后使用 Docker Compose 一键部署了 Dify 社区版平台。 LLM大语言模型私有化部署-使用Dify与Qwen2.5打造专属知识库:在 Dify 平台上,通过普通编排的方式,创建了基于…...
Windows 图形显示驱动开发-WDDM 3.2-自动显示切换(二)
在 GPU0 和 GPU1 之间共享数据 在某些情况下,也许可以在某些时候带来更好的用户体验: GPU0 和 GPU1 来自同一个 IHV。GPU0 可以将操作系统无法解读的显示配置相关信息传递给 GPU1。 数据 Blob 由 GUID 描述,如果 GPU1 的驱动程序能理解数据…...
基于CentOS7安装kubesphere和Kubernetes并接入外部ES收集日志
一、修改所有节点主机名 主节点就修改成master hostnamectl set-hostname master 然后输入bash刷新当前主机名 工作节点1就修改成node1 hostnamectl set-hostname node1 然后输入bash刷新当前主机名 二、全部节点安装依赖并同步时间 yum -y install socat conntrack ebta…...
软考教材重点内容 信息安全工程师 第17章 网络安全应急响应技术原理与应用
17.1 网络安全应急响应概述 网络安全应急响应是针对潜在发生的网络安全事件而采取的网络安全措施。 17.1.1 网络安全应急响应概念 网络安全应急响应是指为应对网络安全事件,相关人员或组织机构对网络安全事件进行监测、预警、分析、响应和恢复等工作。 17.2.3 网络安…...
使用 DeepSeek + OmniParser v2 + UIAutomation 实现 GUI 应用自动化测试的探索
一、背景 UI 自动化测试一直是软件开发中的难点之一。尽管有许多工具和技术(如 Selenium、Appium 等)可以帮助我们实现自动化测试,但这些工具在面对复杂的 UI 变化时,往往需要大量的维护工作。随着人工智能技术的进步,尤其是自然语言处理(NLP)和计算机视觉(CV)技术的…...
Spring Security面试题
Spring Security面试题 基础概念 Q1: Spring Security的核心功能有哪些? public class SecurityBasicDemo {// 1. 基本配置public class SecurityConfigExample {public void configDemo() {ConfigurationEnableWebSecuritypublic class SecurityConfig extends …...
从零开始构建基于DeepSeek的智能客服系统
在当今的数字化时代,智能客服系统已经成为企业与客户沟通的重要桥梁。它不仅能够提升客户体验,还能大幅降低企业的运营成本。本文将带领你从零开始,使用PHP和DeepSeek技术构建一个功能强大的智能客服系统。我们将通过具体的案例和代码示例,深入探讨如何实现这一目标。 1. …...
Linux故障排查和性能优化面试题及参考答案
目录 如何查看 Linux 系统中的 CPU、内存、磁盘等资源使用情况? 什么是 Linux 中的负载(Load Average)?如何解读它? 如何通过 top 和 htop 命令监控系统性能? 如何使用 mpstat 命令来查看 CPU 的利用情况? 如何分析系统 CPU 瓶颈? 如何分析 CPU 瓶颈?如何优化 CP…...
【无人集群系列---大疆无人集群技术进展、技术路线与未来发展方向】
大疆无人集群技术进展、技术路线与未来发展方向 一、技术进展1. 核心技术创新(1)集群协同控制技术(2)感知与能源系统升级 2. 行业应用落地(1)智慧城市与安防(2)应急救援(…...
【亲测有效】百度Ueditor富文本编辑器添加插入视频、视频不显示、和插入视频后二次编辑视频标签不显示,显示成img标签,二次保存视频被替换问题,解决方案
【亲测有效】项目使用百度Ueditor富文本编辑器上传视频相关操作问题 1.百度Ueditor富文本编辑器添加插入视频、视频不显示 2.百度Ueditor富文本编辑器插入视频后二次编辑视频标签不显示,在编辑器内显示成img标签,二次保存视频被替换问题 问题1࿱…...
ubuntu windows双系统踩坑
我有个台式机,先安装的ubuntu,本来想专门用来做开发,后面儿子长大了,给他看了一下星际争霸、魔兽争霸,立马就迷上了。还有一台windows的笔记本,想着可以和他联局域网一起玩,在ubuntu上用wine跑魔…...
云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?
大家好,欢迎来到《云原生核心技术》系列的第七篇! 在上一篇,我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在,我们就像一个拥有了一块崭新数字土地的农场主,是时…...
大语言模型如何处理长文本?常用文本分割技术详解
为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...
零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...
JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作
一、上下文切换 即使单核CPU也可以进行多线程执行代码,CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短,所以CPU会不断地切换线程执行,从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...
大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计
随着大语言模型(LLM)参数规模的增长,推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长,而KV缓存的内存消耗可能高达数十GB(例如Llama2-7B处理100K token时需50GB内存&a…...
在golang中如何将已安装的依赖降级处理,比如:将 go-ansible/v2@v2.2.0 更换为 go-ansible/@v1.1.7
在 Go 项目中降级 go-ansible 从 v2.2.0 到 v1.1.7 具体步骤: 第一步: 修改 go.mod 文件 // 原 v2 版本声明 require github.com/apenella/go-ansible/v2 v2.2.0 替换为: // 改为 v…...
DAY 45 超大力王爱学Python
来自超大力王的友情提示:在用tensordoard的时候一定一定要用绝对位置,例如:tensorboard --logdir"D:\代码\archive (1)\runs\cifar10_mlp_experiment_2" 不然读取不了数据 知识点回顾: tensorboard的发展历史和原理tens…...
Qt学习及使用_第1部分_认识Qt---Qt开发基本流程
前言 学以致用,通过QT框架的学习,一边实践,一边探索编程的方方面面. 参考书:<Qt 6 C开发指南>(以下称"本书") 标识说明:概念用粗体倾斜.重点内容用(加粗黑体)---重点内容(红字)---重点内容(加粗红字), 本书原话内容用深蓝色标识,比较重要的内容用加粗倾…...
【AI News | 20250609】每日AI进展
AI Repos 1、OpenHands-Versa OpenHands-Versa 是一个通用型 AI 智能体,通过结合代码编辑与执行、网络搜索、多模态网络浏览和文件访问等通用工具,在软件工程、网络导航和工作流自动化等多个领域展现出卓越性能。它在 SWE-Bench Multimodal、GAIA 和 Th…...
Unity VR/MR开发-开发环境准备
视频讲解链接: 【XR马斯维】UnityVR/MR开发环境准备【UnityVR/MR开发教程--入门】_哔哩哔哩_bilibili...
