【STL】内部使用哈希表的unordered_map/unordered_set

unordered_map< k , v > 无序映射

内部实现: 哈希表(Hash Table)

特点

  • 无序
  • 高效查找:通过哈希函数直接将值映射到特定位置,增删查时间复杂度O(1)
  • k唯一:每个键只能对应一个值

常用操作

  • find(key):查找key ,返回一个迭代器 。如果找到,迭代器指向该键值对;如果没找到,指向 end()

例如:

cpp 复制代码
unordered_map<int, int> hashtable;
auto it = hashtable.find(nums);
//如果没找到:
it == hashtable.end()
//否则
it->first指向键值对中的键
it->second指向键值对中的值
  • insert({key, value})hashtable[key] = value:插入键值对。
  • erase(key):删除键为 key 的键值对。
  • size():返回键值对的数量。
  • empty():判断是否为空。

unordered_set< k >无序集合

内部实现也是哈希表

特点

  • 唯一性unordered_set 中的元素是唯一的,不允许重复。
  • 无序性 :元素没有固定的顺序。元素的存储位置由其哈希值决定。
  • 基于哈希表unordered_set 内部通常使用哈希表实现。这使得它的插入、删除和查找操作在平均情况下 具有常数时间复杂度 O(1)

常用操作

  • insert(k):插入
  • erase(k):删除值为k的元素
  • find():查找元素
  • clear():清除元素
  • count():统计容器中某个指定元素的出现次数,只会返回1或0

1. 两数之和

要找数值 ,返回**下标,**一个键值对用unordered_map

:数值,:该数所在的下标

利用find寻找和数(比遍历快)

先找再插入,防止自己加自己

cpp 复制代码
class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        unordered_map<int, int> hashtable;//存放  数值:下标
        for (int i = 0; i < nums.size(); ++i) 
        {
            auto it = hashtable.find(target - nums[i]);
            if (it != hashtable.end()) 
            {//如果找到,就返回
                return {it->second, i};
            }
            hashtable[nums[i]] = i;//没有找到,把当前值和下标存入
        }
        return {};
    }
};

49. 字母异位词分组

要找同字母的单词,返回这些单词,也是键值对unordered_map

键:排序后的字母,值:这些字母的单词

这样插入,同字母的单词都在一个键对应着

cpp 复制代码
class Solution {
public:
    vector<vector<string>> groupAnagrams(vector<string>& strs) {
        unordered_map<string,vector<string>> mp;
        vector<vector<string>> ans;
        //排序之和存入map中
        for(auto s:strs)
        {
            string k = s;
            sort(k.begin(),k.end());
            mp[k].emplace_back(s);
        }
        for(auto it = mp.begin();it!=mp.end();it++)
        {
            ans.emplace_back(it->second);
        }
        return ans;
    }
};

128. 最长连续序列

一个vector中可能有多个一样的值,为了避免重复统计这些,可以用unordered_set

这个代码很关键的一步,判断元素是否是连续序列的第一个,即比它小1的元素不存在:if(s.find(it-1)==s.end())//当前元素是序列的第一个元素(这一步用count来写更清楚一些)

尽管代码看起来是嵌套循环,但由于 while 循环受到 if 条件的严格限制,使得每个元素在 while 循环中最多被访问一次,如果if判断不成功,这个循环也就continue了。因此,整个算法的时间复杂度仍然是线性的,即 O(N)。

cpp 复制代码
class Solution {
public:
    int longestConsecutive(vector<int>& nums) {
        if(nums.empty())
        {
            return 0;
        }
        int n = nums.size();
        unordered_set<int> s;
        //将元素插入s,使每一个元素只出现一次
        for(int num:nums)
        {
            s.insert(num);
        }
        int ans = 0;
        int curnum;
        int curlong = 0;
        for(auto & it: s)
        {
            if(s.find(it-1)==s.end())//当前元素是序列的第一个元素
            {
                curnum = it;
                while(s.find(curnum)!=s.end())
                {
                    curlong++;
                    curnum++;
                }
                ans = max(ans,curlong);
                curlong = 0;
            }
        }
        ans = max(ans,curlong);
        return ans;
    }
};
相关推荐
Lisonseekpan17 小时前
雪花算法(Snowflake)技术详解与实战应用
java·分布式·后端·算法
软件算法开发17 小时前
基于秃鹰搜索优化的LSTM深度学习网络模型(BES-LSTM)的一维时间序列预测算法matlab仿真
深度学习·算法·matlab·lstm·时间序列预测·秃鹰搜索优化·bes-lstm
2401_8772742417 小时前
太原理工大学2025数据结构-栈和队列
数据结构·c++·算法
资深web全栈开发17 小时前
LeetCode 1262. 可被三整除的最大和 - 解题思路与代码
算法·leetcode·职场和发展
淀粉肠kk18 小时前
【数据结构】红黑树
数据结构·c++
保持低旋律节奏18 小时前
算法——冗余!哈希表、vector、string适配器的混合使用
数据结构·算法·散列表
weixin_4577600018 小时前
OpenCV 图像处理基础算法详解(一)
图像处理·opencv·算法
做怪小疯子19 小时前
LeetCode 热题 100——链表——相交链表
算法·leetcode·链表
立志成为大牛的小牛20 小时前
数据结构——五十一、散列表的基本概念(王道408)
开发语言·数据结构·学习·程序人生·算法·散列表