哈希表

99 阅读3分钟

哈希表

leetcode.1

  • 链接leetcode.cn/problems/tw…
  • 解题方法:哈希表
    将数组元素存入哈希表,遍历数组求差,差值如果在哈希表中存在则返回下标
  • leetcode解题代码
class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        unordered_map<int, int> hash;
        for (int i = 0; i < nums.size(); i ++){
            int cur = target - nums[i];
            if (hash.count(cur)) return {hash[cur], i};
            hash[nums[i]] = i;
        }
        return {};
    }
};

leetcode.454

  • 链接leetcode.cn/problems/4s…
  • 解题方法:哈希表
    a+b+c+d = 0 => a+b=-(c+d)
    将a+b的和x存入哈希表,如果哈希表中存在-x则为答案
  • leetcode解题代码
class Solution {
public:
    int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
        unordered_map<int, int> hash;
        int res = 0;

        for (auto a: nums1)
            for (auto b: nums2)
                hash[a + b] ++;
        
        for (auto c: nums3)
            for (auto d:nums4)
                res += hash[-(c + d)];

        return res;
    }
};

leetcode.242

  • 链接leetcode.cn/problems/va…
  • 解题方法:哈希表
    将两个字符串存入两个哈希表并记录每个字符出现的次数 每个字符出现的次数相等则返回true,否则返回false
  • leetcode解题代码
class Solution {
public:
    bool isAnagram(string s, string t) {
        unordered_map<char, int> a, b;
        for (auto c: s) a[c] ++;
        for (auto c: t) b[c] ++;
        return a == b;
    }
};

leetcode.383

  • 链接leetcode.cn/problems/ra…
  • 解题方法:哈希表
    题意是判断字符串a是否是字符串b的子集
    将字符串b存入哈希表,如果字符串a中出现了哈希表中没有的字符直接返回false
    如果出现了哈希表中存在的字符则哈希表的value-1
  • leetcode解题代码
class Solution {
public:
    bool canConstruct(string ransomNote, string magazine) {
        unordered_map<char, int> hash;
        for (auto c: magazine) hash[c] ++;
        for (auto c: ransomNote){
            if (!hash[c]) return false;
            hash[c] --;
        }
        return true;
    }
};

leetcode.49

  • 链接leetcode.cn/problems/gr…
  • 解题方法:哈希表
    哈希表中存{key:["","",""]}
    例如{"abc":["abc","acb","cba"]}
    将所有的字符串按字典序排序,如果是字母异位词则一定有相同的字典序
    如"abc","acb","cba"它们的字典序都是"abc"
    key存字典序,value存有相同字典序的字符串
  • leetcode解题代码
class Solution {
public:
    vector<vector<string>> groupAnagrams(vector<string>& strs) {
        unordered_map<string, vector<string>> hash;// {"abc":["abc",[acb],[cab]]}
        
        for (auto str: strs){
            auto c = str;
            sort(c.begin(), c.end());// 将所有字符串按字典序排序
            hash[c].push_back(str);// 按照字典序把字符串存入哈希表
        }
        vector<vector<string>> res;
        for (auto c: hash) res.push_back(c.second);// 将hash中的value拿出来
        return res;
    }
};

哈希表+滑动窗口

leetcode.567

  • 链接leetcode.cn/problems/pe…
  • 解题方法:哈希表+滑动窗口 哈希表存两个字符串,短串称为S1,长串称为S2
    维护滑动窗口左右两个端点[l, r]和计数器
    例如:如果短串中字符a出现了3次,滑动窗口中字符a也出现了3次则计数器+1
    滑动窗口右端点一直移动直到找到所有短串中出现的字符
    右端点每移动一次,如果长串中记录过当前字符S2++,如果S1中字符出现的次数等于S2中字符出现的次数则计数器+1
    当窗口大小大于短串的大小,如果计数器计数等于S1的大小,输出答案
    右端点不动,左端点开始移动
    重复上述过程直到右端点走到长串结尾
  • leetcode解题代码
class Solution {
public:
    bool checkInclusion(string s1, string s2) {
        unordered_map<char, int> s1hash, s2hash;
        for (auto c: s1) s1hash[c] ++;

        int l = 0, r = 0, cnt = 0;

        while (r < s2.size()){
            char a = s2[r];
            r ++;
            if (s1hash.count(a)){
                s2hash[a] ++;
                if (s1hash[a] == s2hash[a]) cnt ++;
            }
            while (r - l + 1 > s1.size()){
                if (cnt == s1hash.size()) return true;
                char b = s2[l];
                l ++;
                if (s1hash.count(b)){
                    if (s1hash[b] == s2hash[b]) cnt --;
                    s2hash[b] --;
                }
            }
        }
        return false;
    }
};

leetcode.438

class Solution {
public:
    vector<int> findAnagrams(string s, string p) {
        unordered_map<char, int> shash, phash;
        for (auto c: p) phash[c] ++;
        
        int l = 0, r = 0, cnt = 0;
        vector<int> res;

        while (r < s.size()){
            char a = s[r];
            r ++;
            if (phash.count(a)){
                shash[a] ++;
                if (shash[a] == phash[a]) cnt ++;
            }
            while (r - l + 1 > p.size()){
                if (cnt == phash.size()) res.push_back(l);
                char b = s[l];
                l ++;
                if (phash.count(b)){
                    if (shash[b] == phash[b]) cnt --;
                    shash[b] --;
                }
            }
        }
        return res;
    }
};

哈希表(集合)

leetcode.349

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        unordered_set<int> set;
        vector<int> res;

        for (auto c: nums1) set.insert(c);
        for (auto c: nums2){
            if (set.count(c)){
                res.push_back(c);
                set.erase(c);
            }
        }
        return res;
    }
};

leetcode.350

  • 链接leetcode.cn/problems/in…
  • 解题方法:哈希表
    unordered_multiset可以包含重复元素,key=value
  • leetcode解题代码
class Solution {
public:
    vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
        unordered_multiset<int> mtset;
        vector<int> res;
        for (auto c: nums1) mtset.insert(c);
        for (auto c: nums2){
            if (mtset.count(c)){
                res.push_back(c);
                mtset.erase(mtset.find(c));// 只删除一个c
            }
        }
        return res;
    }
};