系统学习算法:专题九 穷举vs暴搜vs深搜vs回溯vs剪枝
其中标题的深搜,回溯,剪枝我们之前专题都已经有过学习和了解,这里多了两个穷举和暴搜,其实意思都差不多,穷举就是穷尽力气将所有情况都列举出来,暴搜就是暴力地去一个一个情况搜索,所以就是全部遍历的意思
而实现全部遍历之前,我们需要将所有情况以树状来大致画出来,这棵树就叫做决策树,也就是在上学时数学的某一小节学过的决策树,如下图
将123的所有排列情况列举出来

就是填空一样,将不同情况画出树
那么这就涉及深搜,回溯和剪枝,只不过之前是二叉树,现在变为了多叉树
但过程都大致差不多,只要画出清晰的决策树,就可以将决策转化为代码
题目一:

思路:
先画出决策树,就是上面我们举例的决策树

其中我们需要一个全局变量二维数组ret来存储所有排列的情况,也是我们要返回的结果集
然后我们还需要一个全局变量一维数组path来记录其中一次的排列情况,也就做其中一条路径
然后还需要一个全局变量布尔数组来记录数字的使用情况,没使用过为false,使用过为true
然后我们就开始遍历,但注意我们是深搜dfs,不是宽搜bfs,即虽然画决策树的时候是先填第一个空1,2,3,但实际遍历我们是填1之后,将1对应的所有情况都搜索完之后,再回到2这里,即dfs的搜索顺序,而不是bfs
结束条件也很好想,就是当path的元素个数等于数组元素个数就说明排完了,那么就将该path填入结果集ret中(但注意path要重新new一个出来,不然传的是地址,后续搜索其他排列时,对path修改会连带着修改之前填入的path,即所有path都指向同一个path),填入之后还可以用剪枝稍微优化一下,因为填就说明全部元素用到了,后面的其他元素都没必要再搜索了,因为结果都是不可能的
而往下遍历的时候都是for循环数组的所有元素,调用布尔数组,如果该元素用过就不加,没用过就加,然后继续往下搜索
碰到结束条件后就该回溯,那么就该修改布尔数组和path,将该数的布尔值修改为false,再删除path的最后一个元素
最后返回ret即可
代码:
class Solution {//保存所有全排列的结果集List<List<Integer>> ret=new ArrayList<>();//用于判断该数字是否使用过boolean[] check;//其中一个排列List<Integer> path=new ArrayList<>();public void dfs(int[] nums){//如果排列元素的个数等于数组元素的个数,说明排完了if(path.size()==nums.length){//添加该排列情况(要new一个新的,不然就是传地址)ret.add(new ArrayList<>(path));//剪枝return;}//遍历数组for(int i=0;i<nums.length;i++){//如果当前元素没有使用过if(check[i]==false){//添加该情况path.add(nums[i]);//标记该元素使用过check[i]=true;//选择下一个元素dfs(nums);//回溯,该元素修改为没使用check[i]=false;//删除该元素path.remove(path.size()-1);}}}public List<List<Integer>> permute(int[] nums) { check=new boolean[nums.length];dfs(nums);return ret;}
}
题目二:

思路:
还是先画决策树,不同的决策树画法有不同的代码,但只要决策树画对,代码实现了就一定是对的
求子集大概有两种决策树画法
解法1:

这种决策树画法就是遍历数组,每遍历一个就出现两种决策,选或者不选,最后叶子结点就是所有的子集
代码1:
class Solution {//结果集List<List<Integer>> ret = new ArrayList<>();//其中一个子集List<Integer> path = new ArrayList<>();//k表示到数组的哪一个元素了public void dfs(int[] nums, int k) {//如果遍历完数组了if(k==nums.length){ret.add(new ArrayList<>(path));return;}//选path.add(nums[k]);dfs(nums,k+1);//恢复现场path.remove(path.size()-1);//不选dfs(nums,k+1);}public List<List<Integer>> subsets(int[] nums) {dfs(nums, 0);return ret;}
}
解法2:

这种决策树的画法就是以子集中的元素个数来进行决策,一开始为0个,也就是空集,然后为1个,就是1,2,3,再然后为2个……其中是否选择以当前元素的位置为标准,比如1就找后面的2,3,而2就找后面的3,而3就没得找了,这样子就能避免出现重复的情况
则每一个结点都是一个结果,所以每次dfs的时候都要添加
代码2:
class Solution {//结果集List<List<Integer>> ret = new ArrayList<>();//其中一个子集List<Integer> path = new ArrayList<>();//k表示到数组的哪一个元素了public void dfs(int[] nums, int k) {//先添加ret.add(new ArrayList<Integer>(path));//从当前元素开始往后遍历for (int i = k; i < nums.length; i++) {//添加该元素path.add(nums[i]);//再次基础上往后遍历dfs(nums, i + 1);//恢复现场path.remove(path.size() - 1);}}public List<List<Integer>> subsets(int[] nums) {dfs(nums, 0);return ret;}
}
但综合来看,肯定是解法2更优,因为每一个结点都是结果,没有多余的浪费,而解法1则全部枚举了出来,但最后只选择了叶子结点,非叶子结点就多余了
总结:
解决全排列,集合这种需要枚举许多情况并回溯的,先画出决策树,决策树不唯一,只要思路是对的,通过代码来实现,其中需要注意回溯后要恢复现场,最后就是正确的
相关文章:
系统学习算法:专题九 穷举vs暴搜vs深搜vs回溯vs剪枝
其中标题的深搜,回溯,剪枝我们之前专题都已经有过学习和了解,这里多了两个穷举和暴搜,其实意思都差不多,穷举就是穷尽力气将所有情况都列举出来,暴搜就是暴力地去一个一个情况搜索,所以就是全部…...
解决 Pandas DataFrame 索引错误:KeyError:0
在使用 Pandas 处理数据时,KeyError 是一个常见的问题,尤其是在尝试通过索引访问数据时。本文将通过一个实际案例(使用SKLearn中的MINIST数据集为例),详细分析 KeyError 的原因,并提供解决方法。 1 问题背…...
deepseek的对话风格
概述 deepseek的对话风格,比一般的模型的回答多了思考过程,这是它比较可爱的地方,模型的回答有了思考过程,对用户而言大模型的回答不完全是一个黑盒。 deepseek的对话风格 train_prompt_style """Below is an…...
制造业设备状态监控与生产优化实战:基于SQL的序列分析与状态机建模
目录 1. 背景与挑战 2. 数据建模与采集 2.1 数据表设计 设备状态表(记录设备实时状态变更)...
Javaweb学习之Mysql(Day5)
(一)Mysql概述 (1)MYSQL通用语法 SQL语句可以单行或多行书写,以分号结尾。 SQL语句可以使用空格/缩进来增强语句的可读性(即,空格和缩进不影响代码的执行)。 MySQL数据库的SQL语句不区分大小写。 注释: 1. 单行注释: -- 注释内容 或 # 注释内容 (MySQL 特有 …...
C++ Primer 迭代器
欢迎阅读我的 【CPrimer】专栏 专栏简介:本专栏主要面向C初学者,解释C的一些基本概念和基础语言特性,涉及C标准库的用法,面向对象特性,泛型特性高级用法。通过使用标准库中定义的抽象设施,使你更加适应高级…...
Java的String与StringBuilder例题
package com.jiachen.StringBuilderDemo1;import java.util.Scanner;public class Exercise2 {public static void main(String[] args) {Scanner scanner new Scanner(System.in);String s scanner.nextLine().trim(); // 读取输入并去除前后空格String result;// 根据…...
Vue.js 如何选择合适的组件库
Vue.js 如何选择合适的组件库 大家在开发 Vue.js 项目的时候,都会面临一个问题:我该选择哪个组件库? 市面上有很多优秀的 Vue 组件库,比如 Element Plus、Vuetify、Quasar 等,它们各有特点。选择合适的组件库…...
github下载失败网页打开失败 若你已经知道github地址如何cmd下载
直接打开命令行: winr cmd 输入:git clone 地址 eg:git clone https://github.com/akospasztor/stm32f103-dfu-bootloader...
排序算法--计数排序
统计每个元素出现的次数,直接计算元素在有序序列中的位置,要求数据是整数且范围有限。适用于数据为小范围整数(如年龄、成绩),数据重复率较高时效率更优。可用于小范围整数排序、基数排序的底层排序(作为基数排序的稳定…...
[特殊字符]const在函数前后的作用详解(附经典案例)
理解const在函数前后的位置差异,是掌握C精髓的重要一步。下面用几个超形象的例子,带你彻底搞懂这个知识点! 情况1:const在函数后面(成员函数限定符) 作用:承诺这个成员函数不会修改对象的状态&…...
【字节青训营-7】:初探 Kitex 字节微服务框架(使用ETCD进行服务注册与发现)
本文目录 一、Kitex概述二、第一个Kitex应用三、IDL四、服务注册与发现 一、Kitex概述 长话短说,就是字节跳动内部的 Golang 微服务 RPC 框架,具有高性能、强可扩展的特点,在字节内部已广泛使用。 如果对微服务性能有要求,又希望…...
给AI用工具的能力——Agent
ReAct框架: Reason Action,推理与行动结合 可以借助思维链,用小样本提示展示给模型一个ReAct框架 推理:针对问题或上一步观察的思考 行动:基于推理,与外部环境的一些交互(调用外部工具&…...
Jupyter Lab的使用
Lab与Notebook的区别: Jupyter Lab和Jupyter notebook有什么区别,这里找到一篇博客不过我没细看, Jupyter Lab和Jupyter Notebook的区别 - codersgl - 博客园 使用起来Lab就是一个更齐全、功能更高级的notebook, 启用滚动输出: 有时候一个…...
【从零开始的LeetCode-算法】922. 按奇偶排序数组 II
给定一个非负整数数组 nums, nums 中一半整数是 奇数 ,一半整数是 偶数 。 对数组进行排序,以便当 nums[i] 为奇数时,i 也是 奇数 ;当 nums[i] 为偶数时, i 也是 偶数 。 你可以返回 任何满足上述条件的…...
RabbitMQ深度探索:前置知识
消息中间件: 消息中间件基于队列模式实现异步 / 同步传输数据作用:可以实现支撑高并发、异步解耦、流量削峰、降低耦合 传统的 HTTP 请求存在的缺点: HTTP 请求基于响应的模型,在高并发的情况下,客户端发送大量的请求…...
『 C++ 』中不可重写虚函数的实用案例
文章目录 框架设计:保障核心逻辑稳定避免误操作:防止逻辑混乱确保接口一致:库与API设计 在C编程里,用final关键字修饰、不允许被继承(重写)的虚函数其实很有用。接下来我就结合实际案例,给大家讲…...
Redis - String相关命令
目录 setgetmsetmgetsetnx、setex、psetexincr、incrby、decr、decrby、incrbyfloatappendgetrangesetrangestrlen字符串类型编码方式总结 Redis - String Redis存储的字符串,是直接按二进制方式存储,不会做任何编码转换,存的是什么ÿ…...
pytorch基于FastText实现词嵌入
FastText 是 Facebook AI Research 提出的 改进版 Word2Vec,可以: ✅ 利用 n-grams 处理未登录词 比 Word2Vec 更快、更准确 适用于中文等形态丰富的语言 完整的 PyTorch FastText 代码(基于中文语料),包含࿱…...
3D人脸建模:高精度3D人脸扫描设备快速生成真人脸部3D模型
什么是3D人脸建模? 3D人脸建模,即借助特定技术手段,获取人脸三维数据,并构建出能精准呈现人脸形状、纹理等特征的三维模型。这一技术广泛应用于计算机视觉、人机交互、虚拟现实、影视制作等多个领域,为各行业都带来了前所未有的创…...
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造,完美适配AGV和无人叉车。同时,集成以太网与语音合成技术,为各类高级系统(如MES、调度系统、库位管理、立库等)提供高效便捷的语音交互体验。 L…...
(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)
题目:3442. 奇偶频次间的最大差值 I 思路 :哈希,时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况,哈希表这里用数组即可实现。 C版本: class Solution { public:int maxDifference(string s) {int a[26]…...
linux之kylin系统nginx的安装
一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源(HTML/CSS/图片等),响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址,提高安全性 3.负载均衡服务器 支持多种策略分发流量…...
无法与IP建立连接,未能下载VSCode服务器
如题,在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈,发现是VSCode版本自动更新惹的祸!!! 在VSCode的帮助->关于这里发现前几天VSCode自动更新了,我的版本号变成了1.100.3 才导致了远程连接出…...
可靠性+灵活性:电力载波技术在楼宇自控中的核心价值
可靠性灵活性:电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中,电力载波技术(PLC)凭借其独特的优势,正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据,无需额外布…...
【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】
1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件(System Property Definition File),用于声明和管理 Bluetooth 模块相…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)
推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...
Qt 事件处理中 return 的深入解析
Qt 事件处理中 return 的深入解析 在 Qt 事件处理中,return 语句的使用是另一个关键概念,它与 event->accept()/event->ignore() 密切相关但作用不同。让我们详细分析一下它们之间的关系和工作原理。 核心区别:不同层级的事件处理 方…...
算术操作符与类型转换:从基础到精通
目录 前言:从基础到实践——探索运算符与类型转换的奥秘 算术操作符超级详解 算术操作符:、-、*、/、% 赋值操作符:和复合赋值 单⽬操作符:、--、、- 前言:从基础到实践——探索运算符与类型转换的奥秘 在先前的文…...
