【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;
    }
};
相关推荐
小羊在睡觉5 小时前
力扣84. 柱状图中最大的矩形
后端·算法·leetcode·golang·go
3DVisionary5 小时前
蓝光三维扫描:医疗制造的精度焦虑怎么解
人工智能·算法·制造·蓝光三维扫描·医疗制造·三维检测·义齿检测
好评笔记5 小时前
机器学习面试八股——常用损失函数
人工智能·深度学习·算法·机器学习·校招
weixin_468466855 小时前
全局与局部注意力机制新手实战指南
人工智能·python·深度学习·算法·自然语言处理·transformer·注意力机制
_日拱一卒6 小时前
LeetCode:994腐烂的橘子
java·数据结构·算法·leetcode·深度优先
珂朵莉MM6 小时前
第七届全球校园人工智能算法精英大赛-算法巅峰赛产业命题赛第3赛季优化题--束搜索
人工智能·算法
Omics Pro7 小时前
首个!外源天然产物综合性代谢图谱
数据库·人工智能·算法·机器学习·r语言
voidmort7 小时前
3. 微调(Fine-tuning)与强化学习(RL)的核心思想
python·深度学习·算法
人道领域8 小时前
【LeetCode刷题日记】669.修剪二叉搜索树
开发语言·python·算法
2401_868534788 小时前
【无标题】
数据结构·r语言