哈希表理论基础

哈希表的作用:一般哈希表都是用来快速判断一个元素是否出现集合里。
例如要查询一个名字是否在这所学校里。
要枚举的话时间复杂度是O(n),但如果使用哈希表的话,只需要O(1)就可以做到。

我们只需要初始化把这所学校里学生的名字都存在哈希表里,在查询的时候通过索引直接就可以知道这位同学在不在这所学校里了。

将学生姓名映射到哈希表上就涉及到了hash function,也就是哈希函数。

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

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

刷题笔记day6

242.有效的字母异位词

文章讲解:代码随想录
是否自己做出来通过全部用例:否

遇到的困难/犯的错误

直接看了题解。

自己写的代码

看了题解后写的代码:

class Solution {
public:
    bool isAnagram(string s, string t) {
        int counts1[26] = {0};
        int counts2[26] = {0};
        for (int i = 0; i < s.size(); ++i) {
            ++counts1[s[i] - 'a'];
        }
        for (int i = 0; i < t.size(); ++i) {
            ++counts2[t[i] - 'a'];
        }
        for (int i = 0; i < 26; ++i) {
            if (counts1[i] == counts2[i]) {
                continue;
            }
            else {
                return false;
            }
        }
        return true;
    }
};

看了题解后的收获

善用数组去解决哈希(映射)问题。

349.两个数组的交集

文章讲解:代码随想录
是否自己做出来通过全部用例:否

遇到的困难/犯的错误

直接看了题解。

自己写的代码

看了题解后写的代码:

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        unordered_set<int> set1(nums1.begin(), nums1.end());
        unordered_set<int> res;
        for (auto num : nums2) {
            if (set1.find(num) != set1.end()) {
                res.insert(num);
            }
        }
        vector<int> vec(res.begin(), res.end());
        return vec;
    }
};

看了题解后的收获

如果限制了数值的大小,一般可以用数组。
但如果哈希值比较少、特别分散、跨度非常大(数值跨度非常大),使用数组就造成空间的极大浪费。
这种时候用set。

202.快乐数

文章讲解:代码随想录
是否自己做出来通过全部用例:否

遇到的困难/犯的错误

无限循环跳出的条件没有想到。

自己写的代码

看了题解后写的代码:

class Solution {
public:
    int getsum(int n) {
        int sum = 0;
        while (n) {
            sum += (n % 10) * (n % 10);
            n /= 10;
        }
        return sum;
    }    
    bool isHappy(int n) {
        unordered_set<int> set1;
        while (1) {
            int sum = getsum(n);
            if (sum == 1) {
                return true;
            }
            if (set1.find(sum) != set1.end()) {
                return false;
            }
            else {
                set1.insert(sum);
            }
            n = sum;    
        }
    }
};

看了题解后的收获

循环跳出条件:出现重复的sum。善用set的快速查找功能。

1.两数之和

文章讲解:代码随想录
是否自己做出来通过全部用例:是

遇到的困难/犯的错误

只会暴力解法。

自己写的代码

看了题解后写的代码:

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        unordered_map<int, int> mapping;
        for (int i = 0; i < nums.size(); ++i) {
            int num = target - nums[i];
            auto iter = mapping.find(num);
            if (iter != mapping.end()) {
                return {iter->second, i};
            }
            mapping.insert(pair<int,int>{nums[i], i});
        }
        return {};
    }
};

看了题解后的收获

要想到用哈希法的情况:

  • 查询一个元素是否出现过。
  • 查询一个元素是否在集合内。

每遍历一次加一个元素到unordered_map中,找到的话索引必在i前面。
return {iter->second, i}