算法打卡day5|哈希表篇01|Leetcode 242.有效的字母异位词 、19.删除链表的倒数第N个节点、202. 快乐数、1. 两数之和
哈希表基础知识
哈希表
哈希表关键码就是数组的索引下标,然后通过下标直接访问数组中的元素;数组就是哈希表的一种
一般哈希表都是用来快速判断一个元素是否出现集合里。例如要查询一个名字是否在班级里:
要枚举的话时间复杂度是O(n),但如果使用哈希表的话, 只需要O(1);
哈希函数
把学生的姓名直接映射为哈希表上的索引,然后就可以通过查询索引下标快速知道这位同学是否在这所学校里了。哈希函数如下图所示,通过hashCode把名字转化为数值,一般hashcode是通过特定编码方式,可以将其他数据格式转化为不同的数值,这样就把学生名字映射为哈希表上的索引数字了。
如果hashCode得到的数值大于 哈希表的大小了,此时为了保证映射出来的索引数值都落在哈希表上,会在再次对数值做一个取模的操作,这样我们就保证了学生姓名一定可以映射到哈希表上了。
但就算哈希函数计算的再均匀,也避免不了会有几位学生的名字同时映射到哈希表 同一个索引下标的位置。这就造成了哈希碰撞
哈希碰撞
如图所示,小李和小王都映射到了索引下标 1 的位置,这一现象叫做哈希碰撞。
一般哈希碰撞有两种解决方法, 拉链法和线性探测法。
拉链法
当小李和小王在索引1的位置发生了冲突,发生冲突的元素都被存储在链表中。 这样我们就可以通过索引找到小李和小王了;(数据规模是dataSize, 哈希表的大小为tableSize)
线性探测法
使用线性探测法,一定要保证tableSize大于dataSize。 我们需要依靠哈希表中的空位来解决碰撞问题。
例如冲突的位置,放了小李,那么就向下找一个空位放置小王的信息。所以要求tableSize一定要大于dataSize ,要不然哈希表上就没有空置的位置来存放 冲突的数据了。如图所示:
常见的三种哈希结构
在Java中,哈希结构是一种基于哈希表的数据结构,主要用于快速查找和存取数据。常见的哈希结构包括数组、集合和映射。以下是它们的定义、特性以及使用场景的介绍。
数组(Array)
定义:数组是一种线性数据结构,用于存储固定数量的同类型元素。它提供了通过索引快速访问元素的能力。
特性:数组的大小在创建时就已确定,且之后不能改变。数组在内存中连续分配空间,这有助于快速访问元素。
使用场景:当你需要快速随机访问元素,并且知道元素的数量时,数组是一个不错的选择。例如,处理固定大小的列表、缓冲区或矩阵。
集合(Collection)
定义:集合是Java集合框架的一部分,它提供了一组接口和类,用于存储和操作一组对象。集合框架包括List、Set等多种类型。
特性:集合框架提供了丰富的操作,如添加、删除、遍历元素等。集合可以动态增长和缩小,不需要预先指定大小。
使用场景:集合适用于存储和管理一组对象的场景,尤其是当对象的数量未知或可能变化时。例如,存储用户列表、日志消息或任何动态集合的数据。
映射(Map)
定义:映射是一种键值对的集合,它允许通过唯一的键快速检索值。Java中的Map接口及其实现类(如HashMap、TreeMap等)提供了这种功能。
特性:每个键最多映射到一个值,键不能重复。映射提供了快速的查找、插入和删除操作。
使用场景:映射适用于需要通过键来快速检索值的场景。例如,在数据库查询结果映射、实现属性文件解析、缓存数据等方面非常有用。
算法题
Leetcode 242.有效的字母异位词
题目链接:242.有效的字母异位词
大佬视频讲解:有效的字母异位词视频讲解
个人思路
利用哈希表结构,先遍历一遍a存字符数量到辅助数组,然后再遍历一遍b查值并删除对应字符数量,最后遍历一遍这个辅助数组,如果有字符数量不为0,则不为异位词。
解法
哈希数组
定义一个数组叫做help用来上记录字符串s里字符出现的次数。因为只包括小写字母,所以直接字符a映射为下标0,相应的字符z映射为下标25。再遍历 字符串s的时候,只需要将 s[i] - ‘a’ 所在的元素做+1 操作即可,就能求出一个字母对应出现次数。 然后在遍历字符串t 的时候,对t中出现的字符映射哈希表索引上的数值做-1的操作。那么最后检查一下,help数组如果有的元素不为零0,说明字符串s和t一定是谁多了字符或者谁少了字符。最后如果help数组所有元素都为零0,说明字符串s和t是字母异位词,return true。
class Solution {public boolean isAnagram(String s, String t) {int[] help=new int[26];//辅助数组for(int i =0;i<s.length();i++){ // 求出字符串s对应字母的存在个数help[s.charAt(i) -'a'] ++;}for(int i =0;i<t.length();i++){help[t.charAt(i) -'a'] --;}for(int i=0;i<help.length;i++){ // help数组如果有的元素不为零0,说明字符串s和t 一定是谁多了字符或者谁少了字符。if(help[i]!=0){return false;}}return true; // help数组所有元素都为零0,说明字符串s和t是字母异位词}
}
时间复杂度:O(nlog n);(3个for循环)
空间复杂度:O(1);(没常量大小的辅助数组)
Leetcode 349. 两个数组的交集
题目链接:349.两个数组之间的交集
大佬视频讲解:两个数组之间的交集视频讲解
个人思路
因为结果要求不重复,那可以用set集合;先用一个hashSet存取数组1的值,再看这个hashSet中是否包含数组2的值,如果包含则将数字放入结果集中;
解法
哈希集合
这道题目没有限制数值的大小,就无法使用数组来做哈希表了。而且如果哈希值比较少、特别分散、跨度非常大,使用数组就造成空间的极大浪费。
但如果所有题目都直接使用set 不仅占用空间比数组大,而且速度要比数组慢,set把数值映射到key上都要做hash计算的。在数据量大的情况,差距是非常明显的。
class Solution {public int[] intersection(int[] nums1, int[] nums2) {//nums1 == null判断数组引用是否被初始化//nums1.length == 0 判断数组已经初始化后是否有元素if(nums1 == null || nums1.length == 0 || nums1 == null || nums1.length == 0 ){return new int[0];}Set<Integer> setNum1=new HashSet<>();Set<Integer> result=new HashSet<>();for(int i=0;i<nums1.length;i++){//遍历数组1存值setNum1.add(nums1[i]);}for(int num:nums2){ //遍历数组2的过程中判断哈希表中是否存在该元素if(setNum1.contains(num)){result.add(num);}}return result.stream().mapToInt(x -> x).toArray();//将结果集合转为数组}
}
//最后return的数组,也可以另外申请一个数组存放setRes中的元素int[] arr = new int[resSet.size()];int j = 0;for(int i : resSet){arr[j++] = i;}
时间复杂度:O(n);(两个不嵌套的for循环)
空间复杂度:O(n);(使用多两个set)
Leetcode 202. 快乐数
题目链接:https://leetcode.cn/problems/happy-number/description/
个人思路
快乐数中一个很重要的定义,平方和就是不能重复,否则会无限循环;那可以使用hashSet来解决这道题。
解法
哈希集合
当遇到了要快速判断一个元素是否出现集合里的时候,就要考虑哈希法。所以这道题目使用哈希法,来判断这个sum是否重复出现,如果重复了就是return false, 否则一直找到sum为1为止。
class Solution {public boolean isHappy(int n) {Set<Integer> res=new HashSet<>();//1本身就是快乐数//这个过程结果不能重复出现,不然会无限循环;while(n!=1 && !res.contains(n)){res.add(n);n=comput(n);//计算每个位置上的平方和}return n==1;}public int comput(int n){int sum=0;while(n>0){int temp= n%10;//求余数sum+=temp*temp;//累加平方和n=n/10;//从个位到十位到百位到...}return sum;}
}
时间复杂度:O( n);(模内层循环comput,对于每个n,它会执行n次,因为它是对n的每一位数字进行平方然后求和)
空间复杂度:O(n);( 在最坏的情况下,HashSet
可能会存储所有小于等于n的数字,因此空间复杂度为O(n))
Leetcode 1. 两数之和
题目链接:1. 两数之和
大佬视频讲解:两数之和 视频讲解
个人思路
因为既要求下标,又要求值,可以考虑使用哈希映射这个结构;
解法
哈希映射
在使用map时要明确两点:
1.map用来做什么
map目的用来存放我们访问过的元素,因为遍历数组的时候,需要记录我们之前遍历过哪些元素和对应的下标,这样才能找到与当前元素相匹配的(也就是相加等于target)
2.map中key和value分别表示什么
因为需要判断元素是否出现,还要真的元素的下标,所以 map中的存储结构为 {key:数据元素,value:数组元素对应的下标}。
然后在遍历数组的时候,只需要向map去查询是否有和目前遍历元素匹配的数值,如果有,就找到的匹配对,如果没有,就把目前遍历的元素放进map中;
class Solution {public int[] twoSum(int[] nums, int target) {int[] res=new int[2]; //nums == null判断数组引用是否被初始化//nums.length == 0 判断数组已经初始化后是否有元素if(nums==null || nums.length==0){return res;}Map<Integer,Integer> mapX=new HashMap<>();//key存数组值,value存数组下标for(int i=0;i<nums.length;i++){int temp=target-nums[i];if(mapX.containsKey(temp)){// 遍历当前元素,并在map中寻找是否有匹配的keyres[0]=i;res[1]=mapX.get(temp);break;}mapX.put(nums[i],i); // 如果没找到匹配对,就把访问过的元素和下标加入到map中}return res;}
}
时间复杂度:O(n);(一个for循环)
空间复杂度:O(n);(使用map)
以上是个人的思考反思与总结,若只想根据系列题刷,参考卡哥的网址代码随想录算法官网
相关文章:

算法打卡day5|哈希表篇01|Leetcode 242.有效的字母异位词 、19.删除链表的倒数第N个节点、202. 快乐数、1. 两数之和
哈希表基础知识 哈希表 哈希表关键码就是数组的索引下标,然后通过下标直接访问数组中的元素;数组就是哈希表的一种 一般哈希表都是用来快速判断一个元素是否出现集合里。例如要查询一个名字是否在班级里: 要枚举的话时间复杂度是O(n)&…...
『python爬虫』xpath变化导致无法找到指定元素(持续更新中~)
目录 xpath变化的原因1. 语言设置2. 窗口大小n. 待添加~总结 欢迎关注 『python爬虫』 专栏,持续更新中 欢迎关注 『python爬虫』 专栏,持续更新中 xpath变化的原因 XPath 可能会出现变化的原因有很多,以下是一些常见的情况: 网页…...
人大金仓数据库Kingbase服务SQL基础操作手册
1 kingbase服务 1.1 查看kingbase数据库服务进程 ps -ef|grep kingbase1.2 命令启动kingbase数据库服务 # /opt/Kingbase/ES/V8 为金仓安装目录 # /opt/Kingbase/ES/V8/data 为金仓数据目录 # sys_ctl是数据库服务器启停命令,通过-D选项来来指定数据库数据目录 #…...

赎金信00
题目链接 赎金信 题目描述 注意点 magazine中的每个字符只能在ransomNote中使用一次ransomNote和magazine由小写英文字母组成 解答思路 因为ransomNote和magazine由小写英文字母组成,所以使用大小为26的数组存储magazine中a~z对应出现的次数,ransom…...

如何运行github上的项目
为了讲明白这个过程,特意做了一个相当来说比较好读懂的原理图,希望和我一样初学的小伙伴也能很快上手哈😊 在Github中找到想要部署的项目,这里以BartoszJarocki/CV(线上简历📄)项目为例 先从头…...

机器学习-02-机器学习算法分类以及在各行各业的应用
总结 本系列是机器学习课程的第02篇,主要介绍机器学习算法分类以及在各行各业的应用 本门课程的目标 完成一个特定行业的算法应用全过程: 定义问题(Problem Definition) -> 数据收集(Data Collection) -> 数据分割(Data…...
Java项目学习
一、Java项目学习 1.1 瑞吉外卖(项目提供的资料没笔记) 视频资源:https://www.bilibili.com/video/BV13a411q753/?p1 本人git项目地址:https://gitee.com/xx-xuxin/reggie_take_out.git 瑞吉外卖Day01~Day06没讲的功能(全功能实现…...

npm run dev和npm run serve两个命令的区别
npm run dev和npm run serve两个命令的区别 前端开发过程中运行Vue项目的时候,有时候使用npm run serve命令可以启动项目,有时候却会报错;有时候使用npm run dev命令可以启动项目,有时候却也会报错。是什么原因造成这种情况呢&am…...

ui设计:利用即使设计设计出漂亮样式
目录 一、基本操作 二、具体介绍 6-1 填充图片 6-2 填充色 6-3 图标 右边栏基础设置 右边栏导出编辑 一、基本操作 二、具体介绍 6-1 填充图片 选择其一图片填充 6-2 填充色 6-3 图标 右边栏基础设置 右边栏导出...

[unity]lua热更新——个人复习笔记【侵删/有不足之处欢迎斧正】
一、AssetBundle AB包是特定于平台的资产压缩包,类似于压缩文件 相对于RESOURCES下的资源,AB包更加灵活轻量化,用于减小包体大小和热更新 可以在unity2019环境中直接下载Asset Bundle Browser 可以在其中设置关联 AB包生成的文件 AB包文件…...
Springboot日常总结-@RestController和@Controller的区别
RestController和 Controlle是两种不同的控制器实现,它们的主要区别在于如何处理返回的数据和是否支持跳转到视图页面。 Controller 是一个基本的控制器注解,它允许你将一个类标记为一个Spring MVC控制器处理器。使用 Controller 的类中的方法可以直接返…...

MongoDB之客户端工具与核心概念及基本类型篇
MongoDB之客户端工具与核心概念及基本类型篇 文章目录 MongoDB之客户端工具与核心概念及基本类型篇1. MongoDB是什么?1. 关于MongoDB2. 相关客户端工具1. MongoDB Compass2. Studio 3T3. Navicat for MongoDB4. NoSQL Manager for MongoDB Professional 2.MongoDB相关概念2.1 …...
Essential C++ 编程基础
Essential C 前言1.1 如何撰写 C程序1.2 对象的定义与初始化1.3 撰写表达式1.4 条件语句和循环语句1.5 如何运用Array和Vector1.6 指针带来弹性1.7 文件的读写 前言 通过Essential C笔记的形式对C相关重点知识进行汇总,读者通读此系列文章就可以轻松的把该语言基础捡…...

07 Qt自绘组件:图片预览小组件ImageViewer
系列文章目录 01 Qt自定义风格控件的基本原则-CSDN博客 02 从QLabel聊起:自定义控件扩展-图片控件-CSDN博客 03 从QLabel聊起:自定义控件扩展-文本控件-CSDN博客 04 自定义Button组件:令人抓狂的QToolButton文本图标居中问题-CSDN博客 0…...

Groovy(第九节) Groovy 之单元测试
JUnit 利用 Java 对 Song 类进行单元测试 默认情况下 Groovy 编译的类属性是私有的,所以不能直接在 Java 中访问它们,必须像下面这样使用 setter: 编写这个测试用例余下的代码就是小菜一碟了。测试用例很好地演示了这样一点:用 Groovy 所做的一切都可以轻易地在 Java 程序…...
gprMax3.0随机介质建模
此处利用gprMax建立随机介质模型,采用matlab生成随机数组,保存为HDF5文件,此处为全代码,无需修改即可运行。在gprMax输入文件中使用#geometry_objects_read:读入自定义的随机模型 此文参考其他博主的自定义几何形状模块gprMax3.0建模时如何自定义目标的几何形状_#geomet…...

自动驾驶---行业发展及就业环境杂谈
进入21世纪以来,自动驾驶行业有着飞速的发展,自动驾驶技术(L2---L3)也逐渐落地量产到寻常百姓家。虽然最早期量产FSD的特斯拉有着深厚的技术积累,但是进入2010年以后,国内的公司也逐渐发展起来自己的自动驾…...
Matlab 矩阵基础
Matlab 基础 MATLAB 是“矩阵实验室matrix laboratory”的缩写。其他编程语言大多一次处理一个数字,MATLAB 主要用于处理整个矩阵和数组。 所有 MATLAB 变量都是多维数组,无论数据类型如何。矩阵是常用于线性代数的二维数组。 若要创建一个包含单行中…...

TikTok矩阵系统的功能展示:深入解析与源代码分享!
今天我来和大家说说TikTok矩阵系统,在当今数字化时代,社交媒体平台已成为人们获取信息、交流思想和娱乐放松的重要渠道,其中,TikTok作为一款全球知名的短视频社交平台,凭借其独特的创意内容和强大的算法推荐系统&#…...

Gradio Dataframe sort 问题
Gradio Dataframe sort 问题 1. 问题描述2. 解决办法(临时) 1. 问题描述 使用 Gradio Dataframe 显示表格数据时,默认每个列名右边会有个 sort icon,点击这个 sort icon 后,会按照该列进行升序或者降序排序。 问题点是,如果对表…...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析
今天聊的内容,我认为是AI开发里面非常重要的内容。它在AI开发里无处不在,当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗",或者让翻译模型 "将这段合同翻译成商务日语" 时,输入的这句话就是 Prompt。…...

从WWDC看苹果产品发展的规律
WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...
java 实现excel文件转pdf | 无水印 | 无限制
文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...
STM32+rt-thread判断是否联网
一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...

ETLCloud可能遇到的问题有哪些?常见坑位解析
数据集成平台ETLCloud,主要用于支持数据的抽取(Extract)、转换(Transform)和加载(Load)过程。提供了一个简洁直观的界面,以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...

Module Federation 和 Native Federation 的比较
前言 Module Federation 是 Webpack 5 引入的微前端架构方案,允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...
C# SqlSugar:依赖注入与仓储模式实践
C# SqlSugar:依赖注入与仓储模式实践 在 C# 的应用开发中,数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护,许多开发者会选择成熟的 ORM(对象关系映射)框架,SqlSugar 就是其中备受…...

在WSL2的Ubuntu镜像中安装Docker
Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包: for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...

如何理解 IP 数据报中的 TTL?
目录 前言理解 前言 面试灵魂一问:说说对 IP 数据报中 TTL 的理解?我们都知道,IP 数据报由首部和数据两部分组成,首部又分为两部分:固定部分和可变部分,共占 20 字节,而即将讨论的 TTL 就位于首…...
蓝桥杯 冶炼金属
原题目链接 🔧 冶炼金属转换率推测题解 📜 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V,是一个正整数,表示每 V V V 个普通金属 O O O 可以冶炼出 …...