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

【面试最常考算法】哈希表专题

题号标题题解标签难度
0001两数之和Python数组、哈希表简单
0041缺失的第一个正数Python数组、哈希表困难
0128最长连续序列Python并查集、数组、哈希表中等
0136只出现一次的数字Python位运算、数组简单
0242有效的字母异位词Python哈希表、字符串、排序简单
0442数组中重复的数据数组、哈希表中等
剑指 Offer 61扑克牌中的顺子Python数组、排序简单
0268丢失的数字Python位运算、数组、哈希表、数学、二分查找、排序简单
剑指 Offer 03数组中重复的数字Python数组、哈希表、排序简单

两数之和

// 通过哈希表查找数组中值为 target-nums[i]的值,即为那“两个整数”。如果不是,则存储哈希表并继续向后比对。
// 哈希表的作用:提高查询效率,存放下标值class Solution {public int[] twoSum(int[] nums, int target) {Map<Integer,Integer> map = new HashMap<Integer,Integer>();for(int i = 0 ; i < nums.length ; ++i){// 判断如果哈希表中存在 target-nums[i]的值,则返回这两个数的下标数组if(map.containsKey(target-nums[i])){return new int[]{map.get(target-nums[i]),i};// 之前存入的下标值,现在的下标值。}// 如果判断失败,则将当前值和下标存入哈希表map.put(nums[i],i);}// 如果没有找到,说明不存在,返回一个空数组(创建数组要使用new)return new int[0];}
}

缺失的第一个正数

class Solution {// 正常思路:将数组所有的数放入哈希表,随后从 1 开始依次枚举正整数,并判断其是否在哈希表中,时间复杂度为 O(N),空间复杂度为 O(N)// 原地哈希+哈希表:// 但是要满足时间复杂度为 O(n) 并且只使用常数级别额外空间,我们可以将当前数组视为哈希表。一个长度为 n 的数组,对应存储的元素值应该为 [1, n + 1] 之间,其中还包含一个缺失的元素。// 我们可以遍历一遍数组,将当前元素放到其对应位置上(比如元素值为 1 的元素放到数组第 0 个位置上、元素值为 2 的元素放到数组第 1 个位置上,等等)。
// 然后再次遍历一遍数组。遇到第一个元素值不等于下标 + 1 的元素,就是答案要求的缺失的第一个正数。
// 如果遍历完没有在数组中找到缺失的第一个正数,则缺失的第一个正数是 n + 1。
// 最后返回我们找到的缺失的第一个正数。public int firstMissingPositive(int[] nums) {int n = nums.length;// 第一步:清理数组,将无效值(负数和大于数组长度的值)替换为一个无效值(如 n + 1)for (int i = 0; i < n; i++) {if (nums[i] <= 0 || nums[i] > n) {nums[i] = n + 1; // 用比数组长度大的值替换}}// 第二步:使用索引标记值的存在情况for (int i = 0; i < n; i++) {int num = Math.abs(nums[i]);// 只处理有效的值(1 到 n)if (num <= n) {// 将对应的索引位置的值标记为负数,表示该值存在于数组中nums[num - 1] = -Math.abs(nums[num - 1]);}}// 第三步:查找第一个缺失的正整数for (int i = 0; i < n; i++) {// 如果索引位置的值是正数,则该位置对应的正整数缺失if (nums[i] > 0) {return i + 1; // 返回缺失的正整数}}// 如果所有位置的值都被标记为负数,则说明数组中包含了所有从 1 到 n 的整数// 因此缺失的正整数是 n + 1return n + 1;}
}

最长连续序列

暴力做法有两种思路。

  • 第 1 种思路是先排序再依次判断,这种做法时间复杂度最少是 O(nlog⁡2n)O(nlog2n)。
  • 第 2 种思路是枚举数组中的每个数 num,考虑以其为起点,不断尝试匹配 num + 1num + 2... 是否存在,最长匹配次数为 len(nums)。这样下来时间复杂度为 O(n2)O(n2)。

我们可以使用哈希表优化这个过程。

思路:哈希表

  1. 先将数组存储到集合中进行去重,然后使用 curr_streak 维护当前连续序列长度,使用 ans 维护最长连续序列长度。
  2. 遍历集合中的元素,对每个元素进行判断,如果该元素不是序列的开始(即 num - 1 在集合中),则跳过。
  3. 如果 num - 1 不在集合中,说明 num 是序列的开始,判断 num + 1nums + 2... 是否在哈希表中,并不断更新当前连续序列长度 curr_streak。并在遍历结束之后更新最长序列的长度。
  4. 最后输出最长序列长度。
class Solution {// public int longestConsecutive(int[] nums) {Set<Integer> numSet = new HashSet<Integer>();for(int num : nums ){numSet.add(num);}int result = 0; // 最终序列长度for(int num : numSet){// 如果集合中不存在上一个数,那么就是序列开头if(!numSet.contains(num-1)){int curr = 1;// 当前序列长度int currNum = num; // 当前数字while(numSet.contains(currNum+1)){curr+=1;currNum+=1;}result = Math.max(result , curr);}}return result;}
}

只出现一次的数字

class Solution {// 使用哈希表存储每个数字和该数字出现的次数。遍历数组即可得到每个数字出现的次数,并更新哈希表,最后遍历哈希表,得到只出现一次的数字。// 但是使用位运算才能做到线性时间复杂度和常数空间复杂度// 任何数和 0 做异或运算,结果仍然是原来的数,即 a⊕0=a// 任何数和其自身做异或运算,结果是 0,即 a⊕a=0// 记住:数组中的全部元素的异或运算结果即为数组中只出现一次的数字。public int singleNumber(int[] nums) {int single = 0;for (int num : nums) {single ^= num; // 相当于 single = single ^ num}return single;}
}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 《AI办公类工具PPT系列之二——iSlide AI》
  • PHP-FPM未授权访问漏洞
  • 【整理】后端接口设计和优化相关思路汇总
  • 【C++】单例模式的解析与应用
  • Centos7离线安装Sumo全过程(xerces-c、Cmake、gymnasium等)
  • Windows自动化3️⃣WindowsPC拽起时长问题解决方案
  • Java学习Day30:Mysql 第三章:玄阶高级斗技:八极崩!
  • 查券机器人如何提升电商返利系统的用户体验
  • Visual C++ 2010 学习版
  • Selenium实战:深度解析Python中嵌套Frame与iFrame的定位与切换技巧,解决Selenium定位不到的问题
  • 掌握Jenkins自动化部署:从代码提交到自动上线的全流程揭秘
  • 国内服务器安装Docker提示Failed to connect to download.docker.com port 443的解决方案
  • 使用 Hugging Face 和 Milvus 构建 RAG 系统
  • 机器学习——第十二章计算学习理论
  • 笔记(day21) 多线程以及锁的概念(超级完整版)
  • (ckeditor+ckfinder用法)Jquery,js获取ckeditor值
  • avalon2.2的VM生成过程
  • Eureka 2.0 开源流产,真的对你影响很大吗?
  • React as a UI Runtime(五、列表)
  • Spring思维导图,让Spring不再难懂(mvc篇)
  • Webpack 4 学习01(基础配置)
  • XForms - 更强大的Form
  • 从零到一:用Phaser.js写意地开发小游戏(Chapter 3 - 加载游戏资源)
  • 类orAPI - 收藏集 - 掘金
  • 普通函数和构造函数的区别
  • 如何邀请好友注册您的网站(模拟百度网盘)
  • 使用 5W1H 写出高可读的 Git Commit Message
  • 3月27日云栖精选夜读 | 从 “城市大脑”实践,瞭望未来城市源起 ...
  • 湖北分布式智能数据采集方法有哪些?
  • 如何正确理解,内页权重高于首页?
  • ​卜东波研究员:高观点下的少儿计算思维
  • ​一、什么是射频识别?二、射频识别系统组成及工作原理三、射频识别系统分类四、RFID与物联网​
  • #pragam once 和 #ifndef 预编译头
  • #我与Java虚拟机的故事#连载01:人在JVM,身不由己
  • (Java岗)秋招打卡!一本学历拿下美团、阿里、快手、米哈游offer
  • (Redis使用系列) SpringBoot中Redis的RedisConfig 二
  • (动态规划)5. 最长回文子串 java解决
  • (附源码)ssm教师工作量核算统计系统 毕业设计 162307
  • (六)什么是Vite——热更新时vite、webpack做了什么
  • (五)MySQL的备份及恢复
  • (一)、软硬件全开源智能手表,与手机互联,标配多表盘,功能丰富(ZSWatch-Zephyr)
  • (转)ABI是什么
  • *_zh_CN.properties 国际化资源文件 struts 防乱码等
  • .net 7 上传文件踩坑
  • .NET CF命令行调试器MDbg入门(三) 进程控制
  • .NET COER+CONSUL微服务项目在CENTOS环境下的部署实践
  • .NET DevOps 接入指南 | 1. GitLab 安装
  • .NET 中让 Task 支持带超时的异步等待
  • .NET分布式缓存Memcached从入门到实战
  • [000-01-030].Zookeeper学习大纲
  • [023-2].第2节:SpringBoot中接收参数相关注解
  • [2015][note]基于薄向列液晶层的可调谐THz fishnet超材料快速开关——
  • [AIGC] Redis基础命令集详细介绍
  • [Big Data - Kafka] kafka学习笔记:知识点整理
  • [C\C++]读入优化【技巧】