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

代码随想录——哈希表

当我们想使用哈希法来解决问题的时候,我们一般会选择如下三种数据结构。

  • 数组
  • set (集合)
  • map (映射)

这里数组就没啥可说的了,我们来看一下set。

在C++中,set 和 map 分别提供以下三种数据结构,其底层实现以及优劣如下表所示:

集合底层实现是否有序数值是否可以重复能否更改数值查询效率增删效率
std::set红黑树有序O(log n)O(log n)
std::multiset红黑树有序O(logn)O(logn)
std::unordered_set哈希表无序O(1)O(1)

std::unordered_set底层实现为哈希表,std::set 和std::multiset 的底层实现是红黑树,红黑树是一种平衡二叉搜索树,所以key值是有序的,但key不可以修改,改动key值会导致整棵树的错乱,所以只能删除和增加。

映射底层实现是否有序数值是否可以重复能否更改数值查询效率增删效率
std::map红黑树key有序key不可重复key不可修改O(logn)O(logn)
std::multimap红黑树key有序key可重复key不可修改O(log n)O(log n)
std::unordered_map哈希表key无序key不可重复key不可修改O(1)O(1)

std::unordered_map 底层实现为哈希表,std::map 和std::multimap 的底层实现是红黑树。同理,std::map 和std::multimap 的key也是有序的(这个问题也经常作为面试题,考察对语言容器底层的理解)。

当我们要使用集合来解决哈希问题的时候,优先使用unordered_set,因为它的查询和增删效率是最优的,如果需要集合是有序的,那么就用set,如果要求不仅有序还要有重复数据的话,那么就用multiset。

那么再来看一下map ,在map 是一个key value 的数据结构,map中,对key是有限制,对value没有限制的,因为key的存储方式使用红黑树实现的。

哈希表经典题目

数组作为哈希表

字母异位词等元素上界确定且不大是可以使用数组替换map,这样的空间消耗更小。

字母异位词

classSolution{public:boolisAnagram(string s,string t){intrecord[26]={0};for(inti=0;i<s.size();i++){// 并不需要记住字符a的ASCII,只要求出一个相对数值就可以了record[s[i]-'a']++;}for(inti=0;i<t.size();i++){record[t[i]-'a']--;}for(inti=0;i<26;i++){if(record[i]!=0){// record数组如果有的元素不为零0,说明字符串s和t 一定是谁多了字符或者谁少了字符。returnfalse;}}// record数组所有元素都为零0,说明字符串s和t是字母异位词returntrue;}};

set(集合)作为哈希表

题目没有限制数值的大小,就无法使用数组来做哈希表了。

主要因为如下两点:

  • 数组的大小是有限的,受到系统栈空间(不是数据结构的栈)的限制。
  • 如果数组空间够大,但哈希值比较少、特别分散、跨度非常大,使用数组就造成空间的极大浪费。

所以此时一样的做映射的话,就可以使用set了。

两个数组交集

classSolution{public:vector<int>intersection(vector<int>&nums1,vector<int>&nums2){unordered_set<int>result_set;// 存放结果,之所以用set是为了给结果集去重unordered_set<int>nums_set(nums1.begin(),nums1.end());for(intnum:nums2){// 发现nums2的元素 在nums_set里又出现过if(nums_set.find(num)!=nums_set.end()){result_set.insert(num);}}returnvector<int>(result_set.begin(),result_set.end());}};

map作为哈希表

来说一说:使用数组和set来做哈希法的局限。

  • 数组的大小是受限制的,而且如果元素很少,而哈希值太大会造成内存空间的浪费。
  • set是一个集合,里面放的元素只能是一个key,而两数之和这道题目,不仅要判断y是否存在而且还要记录y的下标位置,因为要返回x 和 y的下标。所以set 也不能用。

map是一种<key, value>的结构,本题可以用key保存数值,用value在保存数值所在的下标。所以使用map最为合适。

两数之和

classSolution{public:vector<int>twoSum(vector<int>&nums,inttarget){std::unordered_map<int,int>map;for(inti=0;i<nums.size();i++){// 遍历当前元素,并在map中寻找是否有匹配的keyautoiter=map.find(target-nums[i]);if(iter!=map.end()){return{iter->second,i};}// 如果没找到匹配对,就把访问过的元素和下标加入到map中map.insert(pair<int,int>(nums[i],i));}return{};}};
http://www.jsqmd.com/news/794274/

相关文章:

  • 只狼mod 深红誓约 法环boss分享 剑星解压即鲁版本
  • SimDoc-MCP:基于MCP协议的文档智能解析与结构化处理工具
  • 协作边缘AI与联邦学习如何重塑去中心化能源系统
  • 从GitFlow到技能流:工程化实践提升团队协作效能
  • 前端工程化:持续集成实战指南
  • 应对海外AIGC检测:初稿AI率飙到97%怎么救?4个结构级优化实测指南
  • Godot游戏引擎集成WebAssembly:高性能跨语言扩展开发指南
  • 方舱数字化快速设计与结构路径协同优化技术【附程序】
  • 英文论文降AI教程:从97%到8%,2026实测的4种文本结构级优化方法
  • Cursor智能编辑器:重塑数据科学工作流,从代码生成到项目级AI协作
  • AI Agent Marketplace:构建去中心化智能体协作平台的技术架构与实践
  • 全中文编程:豆包 AI居然会写单片机程序
  • 通过环境变量统一管理Taotoken密钥提升项目安全与便捷性
  • 复杂室内移动机器人融合建图与平滑路径规划【附代码】
  • AI编码代理统一监控仪表盘:基于环境感知与实时状态聚合的开发者体验优化
  • js脚本翻页自用
  • 嵌入式系统硬件/软件集成挑战与Xilinx优化实践
  • Nintendo Switch大气层系统:解锁游戏自由的终极解决方案
  • EMC预合规测试:传导与辐射发射的实战指南
  • Redis分布式锁进阶第五十七篇
  • Rust轻量级HTTP客户端Hermes-rs:模块化设计与高性能实践
  • 制造企业中央空调模糊PID节能控制系统设计【附程序】
  • 留学生避坑指南:我实测了4种方法,成功将英文论文AI率从97%降到8%
  • DeepSeek V4的突破:探索未来AI意识的可能性
  • AI 第一次自己复制了自己:4 个英文单词,160 小时无限繁殖
  • 本地大模型推理引擎:高性能、可编程的部署与优化实战
  • AI智能体市场架构设计:从标准化封装到安全部署的工程实践
  • VSIPL:嵌入式信号处理的跨平台解决方案
  • Cursor智能体工具包:AI编程助手效率革命,从对话到指令式开发
  • 揭秘2026AI急救点真实部署数据:92%三甲医院已接入,但仅17%通过FDA/CE双认证?