算法模板 哈希表

哈希表一般都是用来快速判断一个元素是否出现集合里,查找操作时间复杂度为O(1)
在这里插入图片描述
哈希碰撞:两个不同的原始值在经过哈希函数运算后得到同样的结果,对应到哈希表同一个位置

解决哈希碰撞的方法:

1.开放地址法
当发生地址冲突时,按照某种方法继续探测哈希表中的其他存储单元,直到找到空位置为止。

2.拉链法
将所有关键字为同义词的记录存储在同一线性链表
在这里插入图片描述

哈希表相关算法题

有效的字母异位词
https://leetcode-cn.com/problems/valid-anagram/

class Solution {
public:
    bool isAnagram(string s, string t) {
        int dicts[26]={0},dictt[26]={0};
        for(int i=0;i<s.size();i++) dicts[s[i]-'a']++;
        for(int i=0;i<t.size();i++) dictt[t[i]-'a']++;

        for(int i=0;i<26;i++)
        {
            if(dicts[i]!=dictt[i]) return false;
        }
        return true;
    }
};

字母异位词分组
https://leetcode-cn.com/problems/group-anagrams/

class Solution {
public:
    vector<vector<string>> groupAnagrams(vector<string>& strs) {
        unordered_map<string,vector<string>> dict;      //key_value
        for(int i=0;i<strs.size();i++)
        {
            string key=strs[i];
            sort(key.begin(),key.end());
            dict[key].push_back(strs[i]);
        }
        vector<vector<string>> ans;
        unordered_map<string,vector<string>>::iterator iter;
        for(iter=dict.begin();iter!=dict.end();iter++)
        {
            ans.push_back(iter->second);
        }
        return ans;
    }
};

找到字符串中所有字母异位词
https://leetcode-cn.com/problems/find-all-anagrams-in-a-string/

class Solution {
public:
    bool eq(vector<int>& dicts,vector<int>& dictp)
    {
        for(int i=0;i<26;i++)
        {
            if(dicts[i]!=dictp[i]) return false;
        }
        return true;
    }
    vector<int> findAnagrams(string s, string p) {
        vector<int> ans;
        if(s.size()<p.size()) return ans;
        vector<int> dicts(26,0),dictp(26,0);
        //记录p中每个字符出现的次数
        for(int i=0;i<p.size();i++)
        {
            dictp[p[i]-'a']++;
        }
        //记录s中第一个子串每个字符出现的次数
        for(int i=0;i<p.size();i++)
        {
            dicts[s[i]-'a']++;
        }
        int cur=0;
        //时间复杂度为O(n)
        while(true)
        {
            if(eq(dicts,dictp)) ans.push_back(cur);
            //窗口向前滑动
            if(cur==s.size()-p.size()) break;
            dicts[s[cur]-'a']--;
            dicts[s[cur+p.size()]-'a']++;
            cur+=1;
        }
        return ans;
    }
};

两个数组的交集
https://leetcode-cn.com/problems/intersection-of-two-arrays/

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        unordered_set<int> dict(nums1.begin(),nums1.end());    //由哈希表实现的无序集合
        unordered_set<int> ans;
        for(int i=0;i<nums2.size();i++)
        {
            if(dict.find(nums2[i])!=dict.end()) ans.insert(nums2[i]);
        }
        return vector<int>(ans.begin(),ans.end());
    }
};

赎金信
https://leetcode-cn.com/problems/ransom-note/

class Solution {
public:
    void cnt(vector<int>& dict,string& s)
    {
        for(int i=0;i<s.size();i++)
        {
            dict[s[i]-'a']++;
        }
    }
    bool canConstruct(string ransomNote, string magazine) {
        vector<int> dict(26,0);
        cnt(dict,magazine);              //计算magazine中用了每个字符多少次
        for(int i=0;i<ransomNote.size();i++)  
        {
            dict[ransomNote[i]-'a']--;
            if(dict[ransomNote[i]-'a']<0) return false;
        }
        return true;
    }
};

快乐数
https://leetcode-cn.com/problems/happy-number/

class Solution {
public:
    bool isHappy(int n) {
        unordered_set<int> dict;
        while(dict.find(n)==dict.end())     //没有环
        {
            dict.insert(n);

            int sum=0;
            while(n!=0)
            {
                sum+=(n%10)*(n%10);
                n/=10;
            }
            n=sum;

            if(n==1) break;
        }
        return n==1;
    }
};

两数之和
https://leetcode-cn.com/problems/two-sum/

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        unordered_map<int,int> map;     //key为数字,value为其下标
        vector<int> ans(2);
        for(int i=0;i<nums.size();i++)
        {
            if(map.find(target-nums[i])==map.end())     //未找到另一个整数
            {
                map[nums[i]]=i;
            }
            else
            {
                ans[0]=i;
                ans[1]=map[target-nums[i]];
                return ans;
            }
        }
        return ans;
    }
};

四数相加 II
https://leetcode-cn.com/problems/4sum-ii/

class Solution {
public:
    int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
        int ans=0;
        unordered_map<int,int> map; //key D[k]+D[l]的数值,value D[k]+D[l]出现的次数
        for(int k=0;k<nums3.size();k++)
        {
            for(int l=0;l<nums4.size();l++)
            {
                if(map.count( nums3[k]+nums4[l] )) map[nums3[k]+nums4[l]]++;
                else map[nums3[k]+nums4[l]]=1;
            }
        }
        for(int i=0;i<nums1.size();i++)
        {
            for(int j=0;j<nums2.size();j++)
            {
                if(map.count( -(nums1[i]+nums2[j])  )) ans+=map[-(nums1[i]+nums2[j])];
            }
        }
        return ans;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值