哈希表 —— 笔记

知识点:

哈希表是根据关键码的值而直接进行访问的数据结构。

当判断一个元素是否在集合里出现时,就要考虑使用哈希法。

常见的三种哈希结构:数组、set(集合),map(映射)。

set和map的底层实现都是红黑树(一种平衡二叉搜索树)。key的值是有序的,只能增删,不能改动

std::set和std::multiset底层实现都是红黑树,std::unordered_set的底层实现是哈希表。

如果题目限制了数值大小,就可以用数组。如果哈希值少,分散跨度大不适用数组。

set占用空间大,速度比数组慢。因为数值映射到key就需要做hash。

题目:

242. 有效的字母异位词 - 力扣(LeetCode) (leetcode-cn.com)

438. 找到字符串中所有字母异位词 - 力扣(LeetCode) (leetcode-cn.com)

    vector<int>pHash(26,0);
    //记录p中各字母出现的次数
    for(int i = 0; i < p.size(); i++) {
        pHash[p[i] - 'a']++;
    }

 切记:在用哈希表想存储字母出现个数的时候,需要用 p[i] - 'a'。

字母异位词分组 - 字母异位词分组 - 力扣(LeetCode) (leetcode-cn.com)

好多map的用法都不是很会。 估计都不记得了。

 349. 两个数组的交集 - 力扣(LeetCode) (leetcode-cn.com)

这道题中有set容器的用法,第一次接触。set只能存不同类型

350. 两个数组的交集 II - 力扣(LeetCode) (leetcode-cn.com)

因为存储多个,不可以用set。这道题是map容器用法。

vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
        //比较两个字符串的大小
        if (nums1.size() > nums2.size()) {
            return intersect(nums2, nums1);
        }
        //将nums1存入容器中
        unordered_map<int,int>num_set;
        for (int num : nums1) {
            num_set[num]++;
        }
        vector<int>res; 
        for (int num : nums2) {
            //如果容器中该元素不为零,则存入,该容器减0
            if(num_set.count(num)) {
                res.push_back(num);
                num_set[num]--;
                //该元素减后为零,删除该元素
                if (num_set[num] == 0) {
                    num_set.erase(num);
                }
            }
        }
    return res;
    }

错误:1、比较两个字符串大小并交换 ,有return,且是nums2在nums1之前,否则会出错。

2、count返回值是0/1,当map中元素个数不为0的时候,要将该元素删除。否则会判断为两个数组仍然交出该元素。

202. 快乐数 - 力扣(LeetCode) (leetcode-cn.com)

这道题存在元素重复出现进而无限循环的情况,所以用哈希表存储,一旦重复出现就跳出循环。

454. 四数相加 II - 力扣(LeetCode) (leetcode-cn.com)

15. 三数之和 - 力扣(LeetCode) (leetcode-cn.com)

 错误:去重逻辑搞不懂。整体解题逻辑也不行。

347. 前 K 个高频元素 - 力扣(LeetCode) (leetcode-cn.com) 

 vector<int> topKFrequent(vector<int>& nums, int k) {
        unordered_map<int,int>m;
        vector<int>res;
        //map数组记录元素和频率
        for (int i : nums) {m[i]++;}
        //找出最大的频率
        int maxk = 0;
        for (auto i : m) {
            if (i.second > maxk)
            maxk = i.second;
        }
        //依次找k个
        while(k > 0) {
            for(auto i : m) {
                if (i.second == maxk) {
                    res.push_back(i.first);
                    k--;
                }
            }
            maxk--;
        }
        return res;
    }

参考文献:

代码随想录 (programmercarl.com)

C++常用语法——unordered_set部分(完善中) - Yu_tiann - 博客园 (cnblogs.com)

C++ map用法_w3cschool

C++ map通过key获取value_liaosongmao1的专栏-CSDN博客_c++ map获取value

(5条消息) C++中的iterator->second_Tian的博客-CSDN博客_second

杂七杂八补充:for(要遍历的数据类型 遍历变量 : 遍历对象)

for(int num : nums2)
//从nums2的int型数组中依次将值赋值给num,将num带入for语句代码块中执行。
//等同于
int num;
for(int i=0;i<nums2.length;i++)
{
    num=nums2[i];
}

set用法

//unordered_set的初始化 - 使用迭代器构造
unordered_set<int> set3(set1.begin(), set1.end());
//find()函数——查找2,找到返回迭代器,失败返回end()
set1.find(2);
//insert()函数——插入元素
set1.insert(3);

map用法 

map_name.count(key,valve)
//用数组方式插入数据
mapPerson[3] = "Jerry";
//map中元素的查找
//find() 函数返回一个迭代器指向键值为 key 的元素,如果没找到就返回指向 map 尾部的迭代器。
if(maplive.find(112) == maplive.end())

unordered_map<key,value> m;
value  =m[key];
m.count(key),m.find(key)

参数:该函数接受强制性参数k,该参数指定要在Map容器中搜索的键。

返回值:如果Map中存在具有给定键的值,则此函数返回1,否则返回0。

多种容器定义插入元素总结:

vector<int>res;
res.push_back(i);

vector<vector<int>>res(n, vector<int>(n, 0));
res[i][j] = num;

unordered_set<int>set3(set1.begin(), set1.end());
set3.insert(3);

unordered_map<int, int>map1;
map1[3] = "Jerry";

 map的first和second的意思

std::map<std::string, int> m = /* fill it */;
auto it = m.begin();

(*it).first会得到key,

(*it).second会得到value。

这等同于it->firstit->second

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值