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

算法系列之回溯算法

_20250226200818.jpg

在计算机科学领域,算法是解决问题的核心。回溯算法作为一种经典的算法设计技巧,以其试错回退的思想,在解决许多复杂问题时展现出强大的能力。本文将深入探讨回溯算法,包括其核心概念、实现步骤、代码示例以及适用场景,帮助读者更好地理解和应用这一算法。

回溯算法概述

  1. 回溯算法

回溯算法(Backtracking Algorithm)是一种通过穷举来解决问题的方法,它的核心思想是从一个初始状态出发,暴力搜索所有可能的解决方案,遇到正确解将其记录,直到找到了所有的解或者尝试了所有的可能为止。

  1. 回溯算法的基本思想

回溯算法的核心思想可以概括为试错回退

  • 试错: 从问题的初始状态出发,逐步构建候选解,尝试每一种可能的选择。

  • 回退: 当发现当前选择无法达到目标状态时,回退到上一步,尝试其他选择,直到找到所有可能的解或确定无解。

  1. 回溯算法的适用场景

回溯算法通常适用于以下类型的问题:

  • 组合问题: 从一组元素中找出所有满足条件的组合,例如子集、排列、组合数等。

  • 约束满足问题: 在满足一定约束条件下,寻找所有可能的解,例如八皇后问题、数独等。

  • 搜索问题: 在图或树等数据结构中搜索特定路径或目标,例如迷宫问题、图的着色问题等。

回溯算法的实现步骤

  1. 确定解空间

首先,需要明确问题的解空间,即所有可能的候选解。解空间通常可以用树形结构表示,每个节点代表一个候选解,边代表选择。

  1. 定义递归函数

使用递归函数来实现回溯算法。递归函数需要包含以下关键步骤:

  • 选择: 在当前状态下,选择一个可行的选项。

  • 递归: 进入下一层递归,尝试构建更完整的候选解。

  • 回退: 如果当前选择无法达到目标状态,则回退到上一步,尝试其他选择。

  1. 剪枝优化

为了提高算法效率,可以使用剪枝技术,即在递归过程中提前排除不可能达到目标状态的分支,减少不必要的搜索。

Java 实现示例:全排列问题

  • 描述:

给出一组数字,返回该组数字的所有排列
例如:
[1,2,3]的所有排列如下
[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2], [3,2,1].
(以数字在数组中的位置靠前为优先级,按字典序排列输出。)

数据范围:数字个数 0<n≤6
要求:空间复杂度 O(n!) ,时间复杂度 O(n!)

  • 示例:

示例1

输入:[1,2,3]返回值:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]

示例2

输入:[1]返回值:[[1]]
  • 分析

我们可以将搜索过程展开成一颗递归树,树中的每个节点代表当前的状态,从根节点开始,通过三轮选择后到达叶子节点,每个节点都对因一个排列。如下图所示:

_20250226205327.jpg

为了实现每个元素只被选择一次,我们引入了一个boolean的数组来标记当前元素是否已经选择,并基于它实现以下的剪枝操作。如下所示:

_20250226214800.jpg

  • 代码实现
public class Permutations {/*** 回溯法,全排列入口类* @param nums* @return*/public static List<List<Integer>> permute(int[] nums) {List<List<Integer>> result = new ArrayList<>();//递归方法backtrack(result, new ArrayList<>(),new boolean[nums.length], nums);return result;}/*** 回溯法,全排列递归方法* @param result* @param temp* @param selected* @param nums*/private static void backtrack(List<List<Integer>> result, List<Integer> temp, boolean[] selected, int[] nums) {// 如果排列的数组长度为数组长度,则说明已经排列完成,将排列结果添加到结果集if (temp.size() == nums.length) {result.add(new ArrayList<>(temp));return;}// 遍历数组,用数组的每个元素一次进行递归for (int i=0 ; i < nums.length; i++) {//剪枝:如果当前元素已经被使用过,则跳过if (selected[i]) {continue;}//排列的集合中添加当前元素temp.add(nums[i]);//将当前元素标记为已选则selected[i] = true;//递归进行下一轮选择backtrack(result, temp, selected, nums);//回退:撤销之前的选择temp.removeLast();//恢复之前的状态selected[i] = false;}}public static void main(String[] args) {int[] nums = {1,2,3};List<List<Integer>> result = permute(nums);System.out.println(result);}
}

总结

回溯算法是一种强大而灵活的算法设计技巧,适用于解决许多复杂的组合、约束满足和搜索问题。通过系统地构建候选解并在必要时回退,回溯算法能够有效地搜索解空间,找到所有可能的解。在实际应用中,结合剪枝等优化技术,可以进一步提高算法的效率。希望本文能够帮助读者更好地理解和应用回溯算法。

相关文章:

算法系列之回溯算法

在计算机科学领域&#xff0c;算法是解决问题的核心。回溯算法作为一种经典的算法设计技巧&#xff0c;以其试错和回退的思想&#xff0c;在解决许多复杂问题时展现出强大的能力。本文将深入探讨回溯算法&#xff0c;包括其核心概念、实现步骤、代码示例以及适用场景&#xff0…...

Uniapp 小程序接口封装与使用

深入理解 Uniapp 小程序接口封装与使用 在 Uniapp 小程序开发中&#xff0c;接口请求是获取和交互数据的关键部分。合理地封装接口不仅能提高代码的可维护性&#xff0c;还能增强项目的健壮性。今天&#xff0c;我们就来详细探讨一下如何在 Uniapp 中进行接口封装、引入以及使…...

Harmony开发笔记(未完成)

一、感想 作为一名拥有11年经验的Android开发者&#xff0c;我亲历了Android从高速发展到如今面临“僧多粥少”的过程。技术的世界瞬息万变&#xff0c;没有一种技术能够让人依赖一辈子。去年初&#xff0c;我自学了鸿蒙系统&#xff0c;并顺利通过了鸿蒙官方的初级和高级认。…...

观成科技:海莲花“PerfSpyRAT”木马加密通信分析

1.概述 在2024年9月中旬至10月&#xff0c;东南亚APT组织“海莲花”通过GitHub发布开源安全工具项目&#xff0c;针对网络安全人员发起了定向攻击。通过对相关攻击活动进行分析&#xff0c;可以将其与一些海莲花的样本关联起来。这些样本的通信数据结构与海莲花此前使用的攻击…...

Spring Boot @Async 注解深度指南

Spring Boot Async 注解深度指南 一、核心使用要点 启用异步支持 必须在启动类或配置类添加 EnableAsync&#xff0c;否则异步不生效。 SpringBootApplication EnableAsync public class Application { ... }线程池配置 默认问题&#xff1a;Spring 默认使用 SimpleAsyncTaskEx…...

windows设置暂停更新时长

windows设置暂停更新时长 win11与win10修改注册表操作一致 &#xff0c;系统界面不同 1.打开注册表 2.在以下路径 \HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings 右键新建 DWORD 32位值&#xff0c;名称为FlightSettingsMaxPauseDays 根据需求填写数…...

Orange 开源项目 - 集成百度智能云-千帆大模型

1 集成百度智能云-千帆大模型 百度智能云-千帆ModelBuilder百度智能云千帆大模型服务与开发平台ModelBuilder&#xff08;以下简称千帆ModelBuilder&#xff09;是面向企业开发者的一站式大模型开发及服务运行平台。千帆ModelBuilder不仅提供了包括文心一言底层模型和第三方开源…...

特斯拉 FSD 算法深度剖析:软件层面全解读

一、引言 特斯拉的 FSD&#xff08;Full Self-Driving&#xff09;系统作为自动驾驶领域的前沿成果&#xff0c;其软件层面的算法设计至关重要。本文将从软件的角度&#xff0c;深入探讨特斯拉 FSD 所采用的算法&#xff0c;包括感知、规划、控制等多个方面&#xff0c;以期为…...

2025/2/17--2/23学习笔记(week1)_C语言

1 整数的存储 只有整数才有原码&#xff0c;反码&#xff0c;补码&#xff0c;原码取反加一&#xff08;除了符号位&#xff09;得到补码。补码的补码会变成原码。 在任何位运算里&#xff0c;都是操作的补码&#xff0c;因为整数在内存里都是以补码存储的 2 移位运算符 移位…...

数据结构:二叉树的数组结构以及堆的实现详解

目录 一.树与二叉树 1.树的概念与相关术语&#xff1a; 2.二叉树&#xff1a; &#xff08;1&#xff09;定义&#xff1a; &#xff08;2&#xff09;特殊的二叉树&#xff1a; &#xff08;3&#xff09;完全二叉树 &#xff08;4&#xff09;二叉树的存储结构&#x…...

AWS S3 如何设置公开访问权限?

1.让整个bucket都有公开访问权限 1.1关闭【阻止公共读】 1.2关闭ACL访问控制 1.3打开桶策略 这样桶内所有的图片就能访问了 2.只开放特定文件让其具有访问权限&#xff1f; 2.1关闭【阻止公共读】 如之前的图示 2.2打开ACL控制 2.3单个文件打开公共读...

使用TortoiseGit配合BeyondCompare实现在Git仓库中比对二进制文件

使用TortoiseGit的比对工具可以直接右键&#xff0c;点击选择比对和上一版本的变化差异&#xff1a; 但是TortoiseGit只能支持比对纯文本文件的变化差异&#xff0c;如果尝试比对二进制文件&#xff0c;会提示这不是一个有效的文本文件&#xff1a; BeyondCompare可以比对二进制…...

8、HTTP/1.0和HTTP/1.1的区别【高频】

第一个是 长连接&#xff1a; HTTP/1.0 默认 短连接&#xff0c;&#xff08;它也可以指定 Connection 首部字段的值为 Keep-Alive实现 长连接&#xff09;而HTTP/1.1 默认支持 长连接&#xff0c;HTTP/1.1是基于 TCP/IP协议的&#xff0c;创建一个TCP连接是需要经过三次握手的…...

Rk3568驱动开发_开发环境的搭建_1

1、环境说明&#xff1a; 需要用官方的程序包&#xff0c;这个程序需要在虚拟机里编译再将镜像烧录到板子里&#xff0c;本质上是给板子上一套Linux操作系统&#xff0c;镜像是.img文件 Linux操作系统被分成了多个模块&#xff0c;编译好后储存在镜像里&#xff0c;本质上就和…...

Solr中得Core和Collection的作用和关系

Solr中得Core和Collection的作用和关系 一&#xff0c; 总结 在Apache Solr中&#xff0c;Core和Collection 是两个核心概念&#xff0c;他们分别用于单机模式和分布式模式&#xff08;SolrCloud&#xff09;中&#xff0c;用于管理和组织数据。 二&#xff0c;Core 定义&am…...

Visual Studio Code 远程开发方法

方法1 共享屏幕远程控制&#xff0c;如 to desk, 向日葵 &#xff0c;像素太差&#xff0c;放弃 方法2 内网穿透 ssh 第二个方法又很麻烦&#xff0c;尤其是对于 windows 电脑&#xff0c;要使用 ssh 还需要额外安装杂七杂八的东西&#xff1b;并且内网穿透服务提供商提供的…...

如何看到 git 上打 tag 的时间

在 Git 中可以通过以下方法查看标签&#xff08;tag&#xff09;的创建时间&#xff1a; 使用 git show 命令&#xff1a; 运行以下命令可以查看某个特定标签的详细信息&#xff0c;包括创建时间&#xff1a; git show 输出中会包含 Tagger 的信息和 Date 字段&#xff0c;显示…...

【HarmonyOS Next】鸿蒙TaskPool和Worker详解 (一)

【HarmonyOS Next】鸿蒙TaskPool和Worker详解 &#xff08;一&#xff09; 一、TaskPool和Worker如何实现多线程&#xff1f;各自特点是什么&#xff1f; 在鸿蒙中通过TaskPool和Worker实现多线程并发&#xff0c;两者都基于Actor并发模型实现。 Actor并发模型&#xff0c;每…...

如何设置HTTPOnly和Secure Cookie标志?

设置HttpOnly和Secure标志于Cookie中是增强Web应用安全性的重要措施。这两个标志帮助防止跨站脚本攻击&#xff08;XSS&#xff09;和中间人攻击&#xff08;MitM&#xff09;。下面是关于如何设置这些标志的具体步骤&#xff1a; 设置方法 在服务器端设置 根据你的服务器端…...

几个api

几个api 原型链 可以阅读此文 Function instanceof Object // true Object instanceof Function // true Object.prototype.isPrototypeOf(Function) // true Function.prototype.isPrototypeOf(Object) // true Object.__proto__ Function.prototype // true Function.pro…...

Google 迎来「DeepSeek 时刻」:TurboQuant算法实现bit无损、×加速、×压缩、零预处理叭

从 UI 工程师到 AI 应用架构者 13 年前&#xff0c;我的工作是让按钮在 IE6 上对齐&#xff1b; 13 年后&#xff0c;我用 fetch-event-source 订阅大模型的“思维流”&#xff0c;用 OCR 解锁图片中的文字——前端&#xff0c;正在成为 AI 产品的第一道体验防线。 最近&#x…...

系统接口文档

系统接口文档是软件开发中不可或缺的技术桥梁&#xff0c;它定义了不同模块或系统之间交互的规则与数据格式。无论是企业级应用还是互联网服务&#xff0c;清晰的接口文档能大幅提升协作效率&#xff0c;降低沟通成本。随着微服务架构和API经济的兴起&#xff0c;接口文档的价值…...

从防御者视角复盘:如果你的PHP代码像DVWA Low级一样写,会被黑客怎么‘爆’?

开发者必修课&#xff1a;当你的PHP代码沦为黑客的游乐场 想象一下这样的场景&#xff1a;你三年前写的PHP代码至今仍在线上运行&#xff0c;而某天突然发现数据库中的所有用户信息被黑客拖库。更可怕的是&#xff0c;攻击者利用的正是你当年随手写下的$id $_REQUEST[id];这样…...

记一次Webshell流量分析 | 添柴不加火甭

1. 哑铃图是什么&#xff1f; 哑铃图&#xff08;Dumbbell Plot&#xff09;&#xff0c;有时也称为DNA图或杠铃图&#xff0c;是一种用于比较两个相关数据点的可视化图表。 它源于人们对更有效数据比较方式的持续探索。 在传统的时间序列比较中&#xff0c;我们通常使用两条折…...

04-微服务篇

文章目录一、Spring Cloud1. Spring Cloud 5大组件有哪些&#xff1f;2. 服务注册和发现是什么意思&#xff1f;Spring Cloud 如何实现服务注册发现&#xff1f;3. 我看你之前也用过nacos&#xff0c;你能说下nacos与eureka的区别&#xff1f;4. 你们项目负载均衡如何实现的&am…...

如何通过wireshark抓取802.11无线网络的数据包

原文链接&#xff1a;https://wiki.wireshark.org/CaptureSetup/WLAN全文总结 本文围绕IEEE 802.11&#xff08;WLAN&#xff09;无线网络抓包环境搭建展开详细说明&#xff0c;核心讲解了在使用Wireshark、TShark等工具抓取无线流量时&#xff0c;不同抓包需求对应的配置方式、…...

NeurIPS 2024新作LightGaussian实战:如何将3DGS模型压缩15倍并提速200+FPS(附完整代码流程)

LightGaussian实战指南&#xff1a;3D高斯模型压缩与加速全流程解析 在3D视觉领域&#xff0c;3D高斯泼溅&#xff08;3D Gaussian Splatting&#xff0c;简称3DGS&#xff09;技术正迅速成为实时渲染的新标杆。然而&#xff0c;原始3DGS模型庞大的存储需求和有限的渲染速度&am…...

C学习历程的总汇

C学习历程的总汇 前言&#xff1a;在学习C时信息闭塞 没有接触到还有"博客"这么一个广阔的复习、学习平台 也就没有提交相关博文 但是电子笔记还是有很多的包括 每天的学习笔记 基础数据结构像顺序表 单向链表 双向链表 栈 队列 堆 均进行了模拟实现 小型游戏扫雷 小…...

保姆级教程:用LangGraph的init_chat_model,5分钟搞定SiliconFlow和本地Ollama模型切换

5分钟掌握LangGraph模型切换术&#xff1a;SiliconFlow与Ollama无缝切换实战 当开发者需要在不同大语言模型之间快速切换时&#xff0c;LangGraph的init_chat_model功能就像一把万能钥匙。想象一下这样的场景&#xff1a;你正在调试一个AI应用&#xff0c;需要在云端高性能模型…...

lite-avatar形象库快速部署:基于CSDN GPU平台的150+2D形象即开即用方案

lite-avatar形象库快速部署&#xff1a;基于CSDN GPU平台的1502D形象即开即用方案 1. 项目介绍 lite-avatar形象库是一个专为数字人应用打造的高质量2D形象资源库&#xff0c;基于HumanAIGC-Engineering/LiteAvatarGallery项目构建。这个形象库最大的特点是提供了150个预训练…...