系统学习算法:专题九 穷举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人脸建模,即借助特定技术手段,获取人脸三维数据,并构建出能精准呈现人脸形状、纹理等特征的三维模型。这一技术广泛应用于计算机视觉、人机交互、虚拟现实、影视制作等多个领域,为各行业都带来了前所未有的创…...
PHP和Node.js哪个更爽?
先说结论,rust完胜。 php:laravel,swoole,webman,最开始在苏宁的时候写了几年php,当时觉得php真的是世界上最好的语言,因为当初活在舒适圈里,不愿意跳出来,就好比当初活在…...
《Playwright:微软的自动化测试工具详解》
Playwright 简介:声明内容来自网络,将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具,支持 Chrome、Firefox、Safari 等主流浏览器,提供多语言 API(Python、JavaScript、Java、.NET)。它的特点包括&a…...

Springboot社区养老保险系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,社区养老保险系统小程序被用户普遍使用,为方…...

华硕a豆14 Air香氛版,美学与科技的馨香融合
在快节奏的现代生活中,我们渴望一个能激发创想、愉悦感官的工作与生活伙伴,它不仅是冰冷的科技工具,更能触动我们内心深处的细腻情感。正是在这样的期许下,华硕a豆14 Air香氛版翩然而至,它以一种前所未有的方式&#x…...

C++:多态机制详解
目录 一. 多态的概念 1.静态多态(编译时多态) 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1).协变 2).析构函数的重写 5.override 和 final关键字 1&#…...
多模态图像修复系统:基于深度学习的图片修复实现
多模态图像修复系统:基于深度学习的图片修复实现 1. 系统概述 本系统使用多模态大模型(Stable Diffusion Inpainting)实现图像修复功能,结合文本描述和图片输入,对指定区域进行内容修复。系统包含完整的数据处理、模型训练、推理部署流程。 import torch import numpy …...

C# 表达式和运算符(求值顺序)
求值顺序 表达式可以由许多嵌套的子表达式构成。子表达式的求值顺序可以使表达式的最终值发生 变化。 例如,已知表达式3*52,依照子表达式的求值顺序,有两种可能的结果,如图9-3所示。 如果乘法先执行,结果是17。如果5…...

什么是VR全景技术
VR全景技术,全称为虚拟现实全景技术,是通过计算机图像模拟生成三维空间中的虚拟世界,使用户能够在该虚拟世界中进行全方位、无死角的观察和交互的技术。VR全景技术模拟人在真实空间中的视觉体验,结合图文、3D、音视频等多媒体元素…...
uniapp 实现腾讯云IM群文件上传下载功能
UniApp 集成腾讯云IM实现群文件上传下载功能全攻略 一、功能背景与技术选型 在团队协作场景中,群文件共享是核心需求之一。本文将介绍如何基于腾讯云IMCOS,在uniapp中实现: 群内文件上传/下载文件元数据管理下载进度追踪跨平台文件预览 二…...

【大模型】RankRAG:基于大模型的上下文排序与检索增强生成的统一框架
文章目录 A 论文出处B 背景B.1 背景介绍B.2 问题提出B.3 创新点 C 模型结构C.1 指令微调阶段C.2 排名与生成的总和指令微调阶段C.3 RankRAG推理:检索-重排-生成 D 实验设计E 个人总结 A 论文出处 论文题目:RankRAG:Unifying Context Ranking…...