算法之哈希表篇

102 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第7天,点击查看活动详情

基础

哈希表中关键码就是数组的索引下标,然后通过下标直接访问数组中的元素
解决的问题:
一般哈希表都是用来快速判断一个元素是否出现集合里
哈希函数:
把学生的姓名直接映射为哈希表上的索引,然后就可以通过查询索引下标快速知道这位同学是否在这所学校里了。--通过hashCode把名字转化为数值,一般hashcode是通过特定编码方式,可以将其他数据格式转化为不同的数值,这样就把学生名字映射为哈希表上的索引数字了。
哈希碰撞:
都映射到了相同的位置值,叫做哈希碰撞。
一般解决方法:拉链法和线性探测法 常见的三种哈希结构

  1. 数组
  2. set(集合)
  3. map(映射)
    哈希法是牺牲了空间换取了时间,因为我们要使用额外的数组,set或者是map来存放数据,才能实现快速的查找。

解题方法

一般哈希表都是用来快速判断一个元素是否出现集合里,所以当两个集合进行比较或者组合(不重复)时可以使用哈希结构进行解题

代码演练

数组力扣题目链接242

    bool isAnagram(string s, string t) {
        if (s.size() != t.size())   return false;
        int re[26] = {0};
        for (auto x: s) re[x - 'a']++;
        for (auto x: t)
        {
            re[x - 'a'] --;
            if (re[x - 'a'] < 0)    return false;
        }
        return true;
    }

集合力扣题目链接349

    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        unordered_set <int> res_s;
        unordered_set <int> nums(nums1.begin(), nums1.end());

        for (auto x: nums2)
        {
            // if (nums.find(x) != nums.end()) res_s.insert(x);
            if (nums.count(x))  res_s.insert(x);
        }

        return vector <int>(res_s.begin(), res_s.end());
    }

map力扣题目链接1

    vector<int> twoSum(vector<int>& nums, int target) {
        unordered_map <int,int> map1;
        for (int i = 0; i < nums.size(); i++)
        {
            auto m = map1.find(target - nums[i]);
            if (m != map1.end())
                return {i, m -> second};
            
            map1.insert(pair<int, int> (nums[i], i));
        }
        return {};
    }

map力扣题目链接454

    int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
        unordered_map<int, int> map1;
        int res = 0;
        for (auto x1: nums1)
            for (auto x2: nums2)
                map1[x1 + x2]++;
        
        for (auto x3: nums3)
            for (auto x4: nums4)
            {
                if (map1.count(0 - x3 - x4))  res += map1[0 - x3 - x4];
            }
        return res;
    }

总结

使用map的空间消耗要比数组大一些,因为map要维护红黑树或者符号表,而且还要做哈希函数的运算。所以数组更加简单直接有效! map是一种<key, value>的结构。 C++中提供了:

  • std::set、map 底层:红黑树
  • std::multiset、multimap 底层:红黑树
  • std::unordered_set、unordered_map 底层:哈希表

应该要保证效率的同时,去选择合适的结构,最大化的简易做题、提高效率。