【算法】回溯算法
回溯算法
什么是回溯
人生无时不在选择。在选择的路口,你该如何抉择 .....

回溯: 是一种选优搜索法,又称为试探法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。
回溯,计算机算法,回溯法也称试探法,它的基本思想是:从问题的某一种状态(初始状态)出发,搜索从这种状态出发所能达到的所有“状态”,当一条路走到“尽头”的时候(不能再前进),再后退一步或若干步,从另一种可能“状态”出发,继续搜索,直到所有的“路径”(状态)都试探过。这种不断“前进”、不断“回溯”寻找解的方法,就称作“回溯法”。--百度百科
一个例子看回溯
给下图的图顶点进行三种颜色着色(红、黄、蓝)
要求:
每个顶点的颜色只能从红、黄、蓝中选一个种。
相邻的两种颜色不能为同一种颜色。

思考方式
暴力推测,查找各种可能...


树型策略

暴力查找结果(从上向下[第n=1行开始],从左边开始):
-
n=1,先取红,n=2取红

- [红、红、红], [红,红,黄],[红,红,蓝]; [红,黄, 红],[红,黄,黄],[红,黄,蓝];[红,蓝,红],[红,蓝,黄],[红,蓝,蓝]
-
n=1, n=2取黄

-
n=2, n=3,取蓝色

-
回溯到根节点,走n=1,取黄色

回溯的一般规律
我们可以针对以上的找色问题,给出以下的一般的解决方案。
-
初始化: 初始化变量
-
找一个合法值,通过遍历(+1/-1)选取所有的可能[可以认为是树的深度]
-
栈记录
-
递归调用
-
回溯已经使用的值
经典题目
全排列
题目
[力扣46] 46. 全排列 - 力扣(LeetCode)
题目描述
给定一个不含重复数字的数组
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]]
解决方案



提交模版
public List<List<Integer>> permute(int[] nums) { }
参考实现
class Solution {
private List<List<Integer>> list = new ArrayList<>();private Stack<Integer> stack = new Stack<>();
public List<List<Integer>> permute(int[] nums) {boolean[] isUsed = new boolean[nums.length];dfs(nums, 0, isUsed);return list;}
private void dfs(int[] nums, int depth, boolean[] isUsed) {if (depth == nums.length) {list.add(new ArrayList<>(stack));return;}
for (int i = 0; i < nums.length; i++) {if (isUsed[i]) {continue;}stack.push(nums[i]);isUsed[i] = true;dfs(nums, depth + 1, isUsed);stack.pop();isUsed[i] = false;}}
}
全排列II
题目
[力扣47] 47. 全排列 II - 力扣(LeetCode)
题目描述
给定一个可包含重复数字的序列 nums ,按任意顺序 返回所有不重复的全排列。
示例 1:
输入:nums = {1,1,2}
输出:
{{1,1,2},{1,2,1},{2,1,1}
}
示例 2:
输入:nums = [1,2,3] 输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
解题思路
提交模版
public List<List<Integer>> permuteUnique(int[] nums) { }
参考实现
class Solution {private final List<List<Integer>> list = new ArrayList<>();private final Stack<Integer> stack = new Stack<>();private final Set<List<Integer>> sets = new HashSet<>();
public List<List<Integer>> permuteUnique(int[] nums) {boolean[] isUsed = new boolean[nums.length];dfs(nums, 0, isUsed);list.addAll(sets);return list;}
/*** @param nums* @param depth 递归的深度,从底层开始到最后一层* @param isUsed 判断当前数据是否使用过*/private void dfs(int[] nums, int depth, boolean[] isUsed) {if (depth == nums.length) {sets.add(new ArrayList<>(stack));return;}
Set<Integer> set = new HashSet<>();//记录重复数据for (int i = 0; i < nums.length; i++) { //遍历数组//数据重复或者使用过则跳过当前数据if (isUsed[i] ) continue;// set.add(nums[i]); //记录选择的数据// System.out.println("set-->" + set);stack.push(nums[i]);isUsed[i] = true;dfs(nums, depth + 1, isUsed);stack.pop();isUsed[i] = false;}}
}
子集问题
题目
[力扣78] 78. 子集 - 力扣(LeetCode)
题目描述
给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。
解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。
示例 1:
输入:nums = [1,2,3] 输出:[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]
示例 2:
输入:nums = [0] 输出:[[],[0]]
解题思路
创建策略树

我们会发现出现大量的无效操作数据。对策略树进行"剪枝"处理。
剪枝- 我们“剪掉”了不满足约束条件的搜索分支,避免许多无意义的尝试,从而提高了搜索效率。

提交模版
public List<List<Integer>> subsets(int[] nums) { }
参考实现
class Solution {List<List<Integer>> list = new ArrayList<>();Stack<Integer> stack = new Stack<>();
public List<List<Integer>> subsets(int[] nums) {dfs(nums, 0);return list;}
private void dfs(int[] nums, int startIndex) {
list.add(new ArrayList<>(stack));if (startIndex >= nums.length) {return;}
for (int i = startIndex; i < nums.length; i++) {stack.push(nums[i]);dfs(nums, i + 1);stack.pop();
}}
}
剪枝优化
class Solution {private final List<List<Integer>> list = new ArrayList<>();private final List<Integer> stack = new ArrayList<>();
public List<List<Integer>> subsets(int[] nums) {boolean[] isUsed = new boolean[nums.length];dfs(nums, 0, isUsed);return list;}
private void dfs(int[] nums, int startIndex, boolean[] isUsed) {
list.add(new ArrayList<>(stack)); //记录扫描的所有节点for (int i = startIndex; i < nums.length; i++) {if (isUsed[i])continue;stack.add(nums[i]);isUsed[i] = true;dfs(nums, i + 1,isUsed);stack.remove(stack.size()-1);isUsed[i] = false;
}}
}
子集II
题目
[力扣90] 90. 子集 II - 力扣(LeetCode)
相关文章:
【算法】回溯算法
回溯算法 什么是回溯 人生无时不在选择。在选择的路口,你该如何抉择 ..... 回溯: 是一种选优搜索法,又称为试探法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标&am…...
AI大模型(如GPT、BERT等)可以通过自然语言处理(NLP)和机器学习技术,显著提升测试效率
在软件测试中,AI大模型(如GPT、BERT等)可以通过自然语言处理(NLP)和机器学习技术,显著提升测试效率。以下是几个具体的应用场景及对应的代码实现示例: 1. 自动生成测试用例 AI大模型可以根据需求文档或用户故事自动生成测试用例。 代码示例(使用 OpenAI GPT API): …...
Centos安装php-8.0.24.tar
查看系统环境 cat /etc/redhat-release 预先安装必要的依赖 yum install -y \ wget \ gcc \ gcc-c \ autoconf \ automake \ libtool \ make \ libxml2 \ libxml2-devel \ openssl \ openssl-devel \ sqlite-devel yum update 1、下载解压 cd /data/ wget https:/…...
机器学习(李宏毅)——RNN
一、前言 本文章作为学习2023年《李宏毅机器学习课程》的笔记,感谢台湾大学李宏毅教授的课程,respect!!! 二、大纲 引例RNN历史基本思想RNN变形RNN训练 三、引例 学习RNN之前先看一个例子: 假设要做一…...
Linux 文件系统inode软硬链接
目录 一、理解文件系统 1、前言 2、磁盘 二、inode 1、创建一个新文件的 4 个操作 三、软硬链接 1、软链接 2、硬链接 3、硬链接的应用 4、软链接的应用 一、理解文件系统 1、前言 在我们电脑文件里,分为打开的文件和未打开的文件,我们在上…...
多目标粒子群优化算法-MOPSO-(机器人路径规划/多目标信号处理(图像/音频))
具体完整算法请跳转:多目标粒子群优化算法-MOPSO-(机器人路径规划/多目标信号处理(图像/音频)) 多目标粒子群优化算法(Multi-Objective Particle Swarm Optimization,MOPSO)是一种基…...
Unity合批处理优化内存序列帧播放动画
Unity合批处理序列帧优化内存 介绍图片导入到Unity中的处理Unity中图片设置处理Unity中图片裁剪 创建序列帧动画总结 介绍 这里是针对Unity序列帧动画的优化内容,将多个图片合批处理然后为了降低Unity的内存占用,但是相对的质量也会稍微降低。可自行进行…...
LayUi点击查看图片组件layer.photos()用法(图片放大预览后滚动鼠标缩放、底部显示自定义标题)
LayUi官方文档更新后发现图片查看组件layer.photos()没有了 记录一下用法 例: <ul id""><li title"" ng-repeat"(val,item) in Obj" ng-click"gszzxxClick(item)"><img ng-src"{{item.src}}" a…...
DAY07 Collection、Iterator、泛型、数据结构
学习目标 能够说出集合与数组的区别数组:1.是引用数据类型的一种2.可以存储多个元素3.数组的长度是固定的 int[] arr1 new int[10]; int[] arr2 {1,2,3};4.数组即可以存储基本类型的数据,又可以存储引用数据类型的数据int[],double[],String[],Student[]集合:1.是引用数据类…...
k8s集群如何赋权普通用户仅管理指定命名空间资源
文章目录 1. 普通用户2. 创建私钥3. 创建 CertificateSigningRequest4. 批准 CertificateSigningRequest5. 创建 kubeconfig6. 创建角色和角色绑定7. 测试 1. 普通用户 创建用户demo useradd demo2. 创建私钥 下面的脚本展示了如何生成 PKI 私钥和 CSR。 设置 CSR 的 CN 和 …...
DeepSeek与ChatGPT的全面对比
在人工智能(AI)领域,生成式预训练模型(GPT)已成为推动技术革新的核心力量。OpenAI的ChatGPT自发布以来,凭借其卓越的自然语言处理能力,迅速占据市场主导地位。然而,近期中国AI初创公…...
C# dynamic 关键字 使用详解
总目录 前言 dynamic 是 C# 4.0 引入的关键字,用于声明动态类型,允许在运行时解析类型和成员,而非编译时。它主要设计用于简化与动态语言(如 Python、JavaScript)的交互、处理未知结构的数据(如 JSON、XML…...
sql server 数据库 锁教程及锁操作
SQL Server数据库 锁的教程 SQL Server 的数据库锁是为了保证数据库的并发性和数据一致性而设计的。锁机制能够确保多个事务不会同时修改同一数据,从而避免数据冲突和不一致的发生。理解 SQL Server 的锁机制对于开发高效、并发性强的数据库应用非常重要。 1. 锁的…...
超全Deepseek资料包,deepseek下载安装部署提示词及本地部署指南介绍
该资料包涵盖了DeepSeek模型的下载、安装、部署以及本地运行的详细指南,适合希望在本地环境中高效运行DeepSeek模型的用户。资料包不仅包括基础的安装步骤,还提供了68G多套独立部署视频教程教程,针对不同硬件配置的模型选择建议,以…...
DeepSeek24小时写作机器人,持续创作高质量文案
内容创作已成为企业、自媒体和创作者的核心竞争力。面对海量的内容需求,人工创作效率低、成本高、质量参差不齐等问题日益凸显。如何在有限时间内产出高质量内容?DeepSeek写作机器人,一款24小时持续创作的智能工具,为企业和个人提…...
用deepseek学大模型08-卷积神经网络(CNN)
yuanbao.tencent.com 从入门到精通卷积神经网络(CNN),着重介绍的目标函数,损失函数,梯度下降 标量和矩阵形式的数学推导,pytorch真实能跑的代码案例以及模型,数据,预测结果的可视化展示, 模型应用场景和优缺点…...
玩客云 IP查找
1.玩客云使用静态IP在不同网段路由器下不能使用,动态不好找IP地址 1.1使用python3 实现自动获取发送 import requests import os import socket# 从环境变量获取 PushPlus 的 token 和群组编码 PUSH_PLUS_TOKEN os.getenv("PUSH_PLUS_TOKEN") PUSH_PLU…...
【鸿蒙Next】鸿蒙应用发布前的准备
图标生成: https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/ide-apply-generated-icon-V5 debug 与 release使用不同的bundle name 鸿蒙多环境配置 https://segmentfault.com/a/1190000045418731...
【OpenCV】入门教学
🏠大家好,我是Yui_💬 🍑如果文章知识点有错误的地方,请指正!和大家一起学习,一起进步👀 🚀如有不懂,可以随时向我提问,我会全力讲解~ ὒ…...
嵌入式 lwip http server makefsdata
背景: 基于君正X2000 MCU Freertoslwip架构 实现HTTP server服务,MCU作为HTTP服务器通过网口进行数据包的传输,提供网页服务。其中设计到LWIP提供的工具makefsdata,常用于将文件或目录结构转换为适合嵌入到固件中的二进制格式。 …...
qemu-kvm源码解析-cpu虚拟化
背景 Qemu 虚拟化中,CPU,内存,中断是虚拟化的核心板块。本章主要对CPU虚拟化源码进行分析 而随着技术的发展包括CPU、内存、网卡等常见外设。硬件层面的虚拟化现在已经是云计算的标配。形成了,qemu作为cpu外层控制面,…...
【蓝桥杯集训·每日一题2025】 AcWing 6123. 哞叫时间 python
6123. 哞叫时间 Week 1 2月18日 农夫约翰正在试图向埃尔茜描述他最喜欢的 USACO 竞赛,但她很难理解为什么他这么喜欢它。 他说「竞赛中我最喜欢的部分是贝茜说 『现在是哞哞时间』并在整个竞赛中一直哞哞叫」。 埃尔茜仍然不理解,所以农夫约翰将竞赛以…...
数据治理中 大数据处理一般都遵循哪些原则
在数据治理中,大数据处理通常遵循以下原则: 最小化原则:企业应只收集实现特定目的所需的数据,避免数据冗余和安全风险。 合法性原则:企业必须遵守相关法律法规,确保数据处理符合法律要求,降低法…...
Linux 多进程生产者消费者模型实现
Linux 多进程生产者消费者模型实现 一、模型核心组件二、关键代码解析1. 信号量封装类(csemp)2. 共享内存初始化3. 生产者核心逻辑4. 消费者核心逻辑 三、关键同步机制信号量使用策略操作时序图 四、扩展知识1. System V与POSIX信号量对比2. 共享内存最佳…...
【Python pro】基本数据类型
一、数字类型 1.1 数字类型的组成 1.1.1 整数 (1)十进制,二进制0b,八进制0o,十六进制0x print(16 0b10000 0o20 0x10) # 输出:True(2)十进制转其他进制 a bin(16) b oct(1…...
sql server查询IO消耗大的排查sql诊断语句
原文链接: sql server查询IO消耗大的排查sql诊断语句-S3软件[code]select top 50 (total_logical_reads/execution_count) as avg_logical_reads , (total_logical_writes/execution_count) as avg_logical_writes , (tota ... https://blog.s3.sh.cn/thread-120-1…...
Spring Boot 自动装配原理深度剖析
一、引言 在 Java 开发领域,Spring 框架无疑是中流砥柱。而 Spring Boot 的出现,更是极大地简化了 Spring 应用的搭建和开发过程。其中,自动装配原理是 Spring Boot 的核心亮点之一,它让开发者无需手动编写大量繁琐的配置代码&am…...
kubernetes源码分析 kubelet
简介 从官方的架构图中很容易就能找到 kubelet 执行 kubelet -h 看到 kubelet 的功能介绍: kubelet 是每个 Node 节点上都运行的主要“节点代理”。使用如下的一个向 apiserver 注册 Node 节点:主机的 hostname;覆盖 host 的参数࿱…...
Golang学习笔记_33——桥接模式
Golang学习笔记_30——建造者模式 Golang学习笔记_31——原型模式 Golang学习笔记_32——适配器模式 文章目录 桥接模式详解一、桥接模式核心概念1. 定义2. 解决的问题3. 核心角色4. 类图 二、桥接模式的特点三、适用场景1. 多维度变化2. 跨平台开发3. 动态切换实现 四、与其他…...
使用EasyExcel和多线程实现高效数据导出
使用EasyExcel和多线程实现高效数据导出 1. 概述 在企业级应用中,数据导出是一个常见的需求。为了提高导出效率,尤其是在处理大量数据时,我们可以结合使用EasyExcel库和多线程技术。本文将详细介绍如何通过EasyExcel和多线程技术实现高…...
