当前位置: 首页 > article >正文

《算法题讲解指南:递归,搜索与回溯算法--穷举vs深搜vs回溯vs剪枝》--12.全排列,13.子集

小叶-duck个人主页❄️个人专栏《Data-Structure-Learning》《C入门到进阶自我学习过程记录》《算法题讲解指南》--优选算法《算法题讲解指南》--递归、搜索与回溯算法《算法题讲解指南》--动态规划算法✨未择之路不须回头已择之路纵是荆棘遍野亦作花海遨游目录什么是回溯算法回溯算法的模板(不要死记硬背)回溯算法的应用12.全排列题目链接题目描述题目示例解法算法思路C算法代码算法总结及流程解析13.子集题目链接题目描述题目示例解法:算法思路:C算法代码(解法一决策树-当前位置选和不选)C算法代码(解法二决策树-i层的子集包含i个元素)算法总结及流程解析结束语什么是回溯算法回溯算法是一种经典的递归算法通常用于解决组合问题、排列问题和搜索问题等。回溯算法的基本思想从一个初始状态开始按照一定的规则向前搜索当搜索到某个状态无法前进时回退到前一个状态再按照其他的规则搜索。回溯算法在搜索过程中维护一个状态树通过遍历状态树来实现对所有可能解的搜索。回溯算法的核心思想“试错”即在搜索过程中不断地做出选择如果选择正确则继续向前搜索否则回退到上一个状态重新做出选择。回溯算法通常用于解决具有多个解且每个解都需要搜索才能找到的问题。回溯算法的模板(不要死记硬背)void backtrack(vectorint path, vectorint choice, ...) { // 满足结束条件 if (/* 满足结束条件 */) { // 将路径添加到结果集中 res.push_back(path); return; } // 遍历所有选择 for (int i 0; i choices.size(); i) { // 做出选择 path.push_back(choices[i]); // 做出当前选择后继续搜索 backtrack(path, choices); // 撤销选择 path.pop_back(); } }其中 path 表示当前已经做出的选择 choices 表示当前可以做的选择。在回溯算法中我们需要做出选择然后递归地调用回溯函数。如果满足结束条件则将当前路径添加到结果集中否则我们需要撤销选择回到上一个状态然后继续搜索其他的选择。回溯算法的时间复杂度通常较高因为它需要遍历所有可能的解。但是回溯算法的空间复杂度较低因为它只需要维护一个状态树。在实际应用中回溯算法通常需要通过剪枝等方法进行优化以减少搜索的次数从而提高算法的效率。回溯算法的应用组合问题组合问题是指从给定的一组数(不重复)中选取出所有可能的k个数的组合。例如给定数集[1,2,3]要求选取k2个数的所有组合。结果为1 [1,2]2 [1,3]3 [2,3]排列问题排列问题是指从给定的一组数(不重复)中选取出所有可能的k个数的排列。例如给定数集[1,2,3]要求选取k2个数的所有排列。结果为1 [1,2]2 [2,1]3 [1,3]4 [3,1]5 [2,3]6 [3,2]子集问题子集问题是指从给定的一组数中选取出所有可能的子集其中每个子集中的元素可以按照任意顺序排列。例如给定数集[1,2,3]要求选取所有可能的子集。结果为1 []2 [1]3 [2]4 [3]5 [1,2]6 [1,3]7 [2,3]8 [1,2,3]总结回溯算法是一种非常重要的算法可以解决许多组合问题、排列问题和搜索问题等。回溯算法的核心思想是搜索状态树通过遍历状态树来实现对所有可能解的搜索。回溯算法的模板非常简单但是实现起来需要注意一些细节比如如何做出选择、如何撤销选择等。12.全排列题目链接46. 全排列 - 力扣LeetCode题目描述题目示例解法算法思路典型的回溯题目我们需要在每一个位置上考虑所有的可能情况并且不能出现重复。通过深度优先搜索的方式不断地枚举每个数在当前位置的可能性并回溯到上一个状态直到枚举完所有可能性得到正确的结果。每个数是否可以放入当前位置只需要判断这个数在之前是否出现即可。具体地在这道题目中我们可以通过一个递归函数 backtrack和标记数组visited 来实现全排列。递归函数设计void backtrack(vectorvectorint res,vectorint nums,vectorbool visited,vectorint ans, int step, int len)参数step(当前需要填入的位置)len (数组长度)返回值无;函数作用查找所有合理的排列并存储在答案列表中。递归流程如下1.首先定义一个二维数组res用来存放所有可能的排列一个一维数组ans用来存放每个状态的排列一个一维数组visited 标记元素然后从第一个位置开始进行递归;2.在每个递归的状态中我们维护一个步数step表示当前已经处理了几个数字;3.递归结束条件当 step 等于 nums数组的长度时说明我们已经处理完了所有数字将当前数组存入结果中;4.在每个递归状态中枚举所有下标i若这个下标未被标记则使用nums数组中当前下标的元素:a.将visited[i]标记为 1;b.ans 数组中第 step个元素被nums[i]覆盖;c.对第step1个位置进行递归;d.将visited[i]重新赋值为0表示回溯;5.最后返回 res。特别地我们可以不使用标记数组直接遍历 step 之后的元素(未被使用)然后将其与需要递归的位置进行交换即可。C算法代码class Solution { public: vectorvectorint ret; bool check[7]; vectorint path; vectorvectorint permute(vectorint nums) { dfs(nums); return ret; } void dfs(vectorint nums) { if(path.size() nums.size()) { ret.push_back(path); return; } for(int i 0; i nums.size(); i) { if(check[i] false) { path.push_back(nums[i]); check[i] true; dfs(nums); path.pop_back(); check[i] false; } } } };算法总结及流程解析13.子集题目链接78. 子集 - 力扣LeetCode题目描述题目示例解法:算法思路:为了获得nums数组的所有子集我们需要对数组中的每个元素进行选择或不选择的操作即nums数组一定存在2^(数组长度)个子集。对于查找子集具体可以定义一个数组来记录当前的状态并对其进行递归。对于每个元素有两种选择:1.不进行任何操作;2.将其添加至当前状态的集合。在递归时我们需要保证递归结束时当前的状态与进行递归操作前的状态不变而当我们在选择进行步骤2进行递归时当前状态会发生变化因此我们需要在递归结束时撤回添加操作即进行回溯。递归函数设计void backtrack(vectorvectorint res,vectorint nums,vectorbool visited,vectorint ans, int step, int len)参数step(当前需要填入的位置)len (数组长度)返回值无;函数作用查找所有合理的排列并存储在答案列表中。递归流程如下:1.递归结束条件:如果当前需要处理的元素下标越界则记录当前状态并直接返回;2.在递归过程中对于每个元素我们有两种选择不选择当前元素直接递归到下一个元素;选择当前元素将其添加到数组末尾后递归到下一个元素然后在递归结束时撤回添加操作;3.所有符合条件的状态都被记录下来返回即可。C算法代码(解法一决策树-当前位置选和不选)class Solution { public: vectorvectorint ret; vectorint path; vectorvectorint subsets(vectorint nums) { dfs(nums, 0); return ret; } //解法一决策树-当前位置选和不选 void dfs(vectorint nums, int i) { if(i nums.size()) { ret.push_back(path); return; } //选择1不选当前值 dfs(nums, i 1); //选择2选择当前值 path.push_back(nums[i]); dfs(nums, i 1); //回溯-恢复现场 path.pop_back(); } };C算法代码(解法二决策树-i层的子集包含i个元素)class Solution { public: vectorvectorint ret; vectorint path; vectorvectorint subsets(vectorint nums) { dfs(nums, 0); return ret; } //解法二决策树-i层的子集包含i个元素 void dfs(vectorint nums, int index) { ret.push_back(path); for(int i index; i nums.size(); i) { path.push_back(nums[i]); dfs(nums, i 1); //回溯-恢复现场 path.pop_back(); } } };算法总结及流程解析结束语到此12.全排列13.子集 这两道算法题就讲解完了。全排列问题通过标记数组记录已使用元素子集问题则采用决策树方法处理每个元素的选/不选情况。两种解法都体现了回溯算法尝试-回溯的特点并强调了恢复现场的重要性。希望大家能有所收获

相关文章:

《算法题讲解指南:递归,搜索与回溯算法--穷举vs深搜vs回溯vs剪枝》--12.全排列,13.子集

🔥小叶-duck:个人主页 ❄️个人专栏:《Data-Structure-Learning》《C入门到进阶&自我学习过程记录》 《算法题讲解指南》--优选算法 《算法题讲解指南》--递归、搜索与回溯算法 《算法题讲解指南》--动态规划算法 ✨未择之路&#xff0…...

OpenClaw内存泄漏排查:Qwen3-32B长会话任务监控与优化

OpenClaw内存泄漏排查:Qwen3-32B长会话任务监控与优化 1. 问题背景:当OpenClaw遇上长会话任务 上周我尝试用OpenClaw自动化处理一批技术文档的摘要生成工作。这个任务需要连续处理上百个Markdown文件,每个文件都需要调用Qwen3-32B模型进行多…...

从收音机到手机:聊聊LC振荡器(电容三端式)的演进与选型实战

从收音机到手机:LC振荡器的技术演进与工程选型实战 上世纪40年代,一台采用考毕兹电路的调幅收音机需要每天校准频率;而今天,你的智能手机蓝牙耳机却能稳定工作数月无需调整——这背后是LC振荡器技术近百年的进化史。作为射频电路的…...

Windows虚拟机中部署黑群晖7.2 NAS:从零搭建到内网穿透全攻略

1. 为什么要在Windows虚拟机跑黑群晖? 很多朋友第一次听说在Windows里装黑群晖都会觉得奇怪——NAS不是应该用实体机吗?我最初也是这么想的,直到去年家里老笔记本闲置下来,实测发现用虚拟机跑群晖不仅省电省钱,还能实现…...

要使用vue脚手架来创建一个项目的步骤

1、安装node.js 1.1、node.js的作用: 1.1.1、自带包管理器 node.js是npm和yarn的运行环境,没有node.js就运行不了npm命令和yarn命令。 (1)npm是官方的,node.js自带的,负责下载,安…...

MicroStation效率倍增:从快捷键到三维建模的进阶实战指南

1. 快捷键系统:从基础到高阶的全面掌握 MicroStation的快捷键系统就像设计师手中的瑞士军刀,熟练使用能让工作效率提升300%以上。我刚开始接触MicroStation时,总是一边画图一边在菜单栏里翻找工具,后来发现老工程师们手指在键盘上…...

告别软件瓶颈:手把手教你用K7 FPGA和纯VHDL代码搭建自己的10G TCP服务器

突破10G网络性能极限:用K7 FPGA构建零延迟TCP服务器的实战指南 当数据中心遇到性能天花板时,传统软件协议栈的局限性便暴露无遗。我曾亲眼见证某量化交易团队因为TCP栈额外增加的3微秒延迟,导致全年错失超过2.8亿元的交易机会——这恰恰是硬…...

基于单片机双向可控硅控制交流电导通脚

一、系统功介绍 基于单片机双向可控硅控制交流电导通脚的设计,是通过单片机精确控制双向可控硅的触发时机,实现交流电的导通与断开,广泛应用于交流调压、调光、电机调速及无触点开关等场景。 以下从核心原理、硬件设计、软件实现、应用场景及…...

Using Vulkan -- Atomics

原子操作的类型变体 想要更好地理解各类相关扩展,首先需要了解 Vulkan 提供的不同原子操作类型,主要分为以下维度: 数据类型 floatint 位宽 16 bit32 bit64 bit 操作类型 加载(loads)存储(stores&am…...

【人工智能】CCF-A/B/C类期刊最新解析:影响因子、分区与投稿指南

1. CCF期刊分类体系解析 第一次接触CCF期刊目录时,我也被A/B/C的分类搞得一头雾水。简单来说,中国计算机学会(CCF)将计算机领域的国际学术期刊分为A、B、C三个等级,其中A类代表该领域的顶级期刊,相当于学术…...

零基础搞懂Harness Engineering(超详细保姆级教程),告别AI胡说八道,收藏这一篇就够了!

2026年第一季度,大模型应用层最具统治力的热词,绝对是「Harness」。 今年三月,LangChain 发布了一篇题为《The Anatomy of an Agent Harness》的实证文章,彻底点燃了所有人的焦虑与狂热。他们在这份报告里引用了一个实验数据对比…...

JavaScript中类方法中this指向丢失的场景与对策

JavaScript类中方法的this丢失本质是函数单独调用时上下文丢失;常见于回调传递、解构赋值、异步操作三类场景,可通过箭头函数、bind绑定、类字段语法等方案解决。在 JavaScript 类中,方法里的 this 指向丢失,本质是函数被“单独调…...

C#怎么批量删除指定格式文件_C#如何遍历清空目录【干货】

应先用Directory.GetFiles精准匹配再逐个删除,避免Directory.Delete误删或报错;需处理权限、占用、只读等异常,并注意中文路径、ACL跳过、句柄未释放等问题。用 Directory.GetFiles 精准匹配再删,别直接 Directory.Delete批量删指…...

uni-app怎么获取手机端的当前电量信息 uni-app调用系统底层电池状态【实战】

Vue2项目中uni.getBatteryInfo不可用,需通过plus.android/plus.ios调原生:Android监听ACTION_BATTERY_CHANGED广播并计算百分比,iOS需先启用监控并处理归一化值,H5和小程序需分别兼容。uni.getBatteryInfo 在 Vue2 项目里根本不能…...

Cgo回调中处理 const char- 参数的正确方法

本文详解如何在 Cgo 中为 C 回调函数正确声明和实现接收 const char* 参数的 Go 导出函数,解决因类型不匹配导致的编译错误,并提供可直接复用的类型别名方案与完整示例。 本文详解如何在 cgo 中为 c 回调函数正确声明和实现接收 const char* 参数的…...

OpenClaw学习监督:千问3.5-9B定制的个性化学习计划

OpenClaw学习监督:千问3.5-9B定制的个性化学习计划 1. 为什么需要AI学习监督助手 去年我开始自学机器学习时,经常陷入"东一榔头西一棒子"的困境。今天看CNN,明天学Transformer,没有系统规划,三个月后发现知…...

递归封神!二叉树两大究极考题:路径总和 III + 最近公共祖先|面试原地 AC

目录 前言 一、路径总和 III:任意起点、任意终点的路径计数 思路一句话总结 完整 AC 代码 关键点小白精讲 二、二叉树的最近公共祖先:后序遍历的神级应用 思路一句话总结 完整 AC 代码 小白秒懂逻辑 三、两道题核心思想总结 路径总和 III 最近…...

损失2万块买来的教训:出海独立站如何从“裸奔”走向云原生高可用架构?

上个月,我帮一位做跨境宠物用品的老板做了一次紧急的架构救火。起因是他发现网站在正常投放 Google Ads 的情况下,突然大面积访问超时。我介入排查后发现,服务器 CPU 已经飙升到 100%,Nginx 日志里密密麻麻全是针对 /api/checkout…...

.shop 域名 SEO 优化有什么技巧

.shop 域名 SEO 优化有什么技巧 在当今互联网时代,域名不仅仅是一个网站的地址,更是品牌的重要组成部分。特别是随着电子商务的蓬勃发展,.shop 域名逐渐成为电商网站的首选。但是,仅有一个好的.shop 域名并不足以让你在搜索引擎上…...

NCP1654 引脚6(FB):外围电阻、电压范围、计算与测试方法

NCP1654 引脚6(FB):外围电阻、电压范围、计算与测试方法 引脚6(FB)是NCP1654的输出电压反馈/关断控制脚,核心功能是采样PFC输出母线电压,送入内部误差放大器,稳定输出电压&#xff1…...

CSS如何为提示框设置特定颜色标识_使用语义化的自定义属性

安装Npgsql包需区分用途:纯ADO.NET用Npgsql,EF Core用Npgsql.EntityFrameworkCore.PostgreSQL;连接字符串须含Password和Timeout;参数用:name非name;异步操作必须await;连接池需合理配置。安装 Npgsql 包时…...

SEO_2024年SEO最新趋势与实战操作解析

2024年SEO最新趋势解析:如何在百度上取得高排名 随着互联网的迅速发展,2024年的SEO(搜索引擎优化)又迎来了新的变化和挑战。在百度这个最大的中文搜索引擎中,如何提升网站的排名成为每一个网站运营者的共同目标。本文…...

mmdetection, mmclassification, mmsegmentation, mmdetection3d, mmselfsup,mmrazor, openmmlab系列答疑,私有数据集

mmdetection, mmclassification, mmsegmentation, mmdetection3d, mmselfsup,mmrazor, openmmlab系列答疑,私有数据集适配,私有模型适配,分布式训练等 欢迎带问题咨询#辅导作业神器 #助力学习好物...

【UVM】UVM类型转换方法详解与代码示例--$cast/静态转换/虚方法/Factory覆盖/类型识别+转换/Callback机制

UVM类型转换方法详解与代码示例 一、六种类型转换方法的代码示例 1. $cast方法(运行时检查) // 基类和子类定义 class Base extends uvm_object;virtual function void display();`uvm_info("BASE", "Base class display", UVM_LOW);endfunction endc…...

考虑一次调频与二次调频及机组差异化特性的风光水火储双目标动态调度研究(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...

西门子三菱 PLC 编程教程合集|零基础到进阶学习资料整理

在工业自动化领域,PLC 编程是核心技能之一,想要系统掌握西门子、三菱两大品牌的 PLC 编程知识,合适的学习资料能让学习效率事半功倍。本次整理了一批涵盖不同学习阶段的 PLC 编程资料,从零基础入门到针对性机型实操,覆…...

Unity3D实战:从零构建竖屏飞机大战游戏

1. 竖屏游戏的基础设置 第一次打开Unity时,默认是横屏模式。我们需要做的第一件事就是把游戏改成竖屏。这个操作看似简单,但很多新手容易忽略几个关键点。在Game窗口右上角找到分辨率设置,点击加号新建一个预设。这里要特别注意选择"Asp…...

macOS极简安装OpenClaw:gemma-3-12b-it镜像10分钟体验

macOS极简安装OpenClaw:gemma-3-12b-it镜像10分钟体验 1. 为什么选择OpenClawGemma组合 上周我在测试自动化工作流时,偶然发现OpenClaw这个开源框架。它最吸引我的是能直接在本地电脑上实现"AI操控电脑"——就像有个数字员工帮你点击鼠标、整…...

嵌入式开发从入门到精通:C语言、RTOS与Linux实战

1. 嵌入式学习之路:从入门到进阶的完整指南作为一名在嵌入式领域摸爬滚打多年的工程师,我深知这个领域的学习曲线有多陡峭。从最初的51单片机到如今的Linux系统开发,嵌入式技术涵盖了硬件设计、底层驱动、操作系统、网络通信等多个维度。今天…...

树莓派实战指南:从零搭建DHT11温湿度监测系统

1. 认识你的硬件伙伴:DHT11与树莓派 第一次拿到DHT11温湿度传感器时,我盯着这个比指甲盖还小的模块看了半天——就这么个小东西能测量环境数据?后来实测发现它虽然精度不如实验室设备,但家用完全够用。DHT11通过单总线协议通信&am…...