初级数据结构——哈希表题库(c++)

目录

前言

这期就是有关哈希表的二十多道实战题,我们一起学习,有错误的地方希望大家指正。
在这里插入图片描述

1.——面试题 17.04. 消失的数字

(蓝色字体可以点进去看原题)
代码题解

class Solution {
public:
    int missingNumber(vector<int>& nums) {
        unordered_map<int,int>hash;
        for(int i=0;i<nums.size();i++){
            hash[nums[i]]=1;
        }
        for(int i=0;;i++){
            if(hash.find(i)==hash.end())return i;//没找到i,就说明哈希表被找完了就等于hash.end()
        }
        return -1;
    }
};

2.——41. 缺失的第一个正数

class Solution {
public:
    int firstMissingPositive(vector<int>& nums) {
        unordered_map<int,bool>hash;
        for(int i=0;i<nums.size();i++){
            hash[nums[i]]=true;
        }
        for(int i=1;;i++){
            if(hash.find(i)==hash.end())return i;
        }
    }
};

3.——LCR 173. 点名

class Solution {
public:
    int takeAttendance(vector<int>& records) {
        unordered_map<int,int>hash;
        for(int i=0;i<records.size();i++){
            hash[records[i]]=1;
        }
        for(int i=0;;i++){
            if(hash.find(i)==hash.end())return i;
        }
    }
};

4.——268. 丢失的数字

class Solution {
public:
    int missingNumber(vector<int>& nums) {
        unordered_map<int,int>hash;
        for(int i=0;i<nums.size();i++){
            hash[nums[i]]=1;
        }
        for(int i=0;;i++){
            if(hash.find(i)==hash.end())return i;
        }
    }
};

5.——LCR 120. 寻找文件副本

class Solution {
public:
    int findRepeatDocument(vector<int>& documents) {
        unordered_map<int,bool>hash;
        vector<int>ret;
        for(int i=0;i<documents.size();i++){
            if(hash.find(documents[i])!=hash.end())return documents[i];
            hash[documents[i]]=true;
        }
        return 0;
    }
};

6.——575. 分糖果

class Solution {
public:
    int distributeCandies(vector<int>& candyType) {
        unordered_map<int,bool>hash;
        int len=candyType.size();
        for(int i=0;i<len;i++){
            hash[candyType[i]]=true;
        }
        return min(hash.size(),len/2);//其实也就是不同种糖的个数和n/2求最小值
    }
};

7.——1. 两数之和

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        unordered_map<int,int>hash;
        for(int i=0;i<nums.size();i++){
            auto p=hash.find(target-nums[i]);//如果找到在哈希表中能找到target-num[i]这个数,就返回他们的下标
            if(p!=hash.end()){
                return {i,p->second};//
            }
            hash[nums[i]]=i;//标记这个值的下标
        }
        return {};
    }
};

8.——387. 字符串中的第一个唯一字符

class Solution {
public:
    int firstUniqChar(string s) {
        int count[256];
        memset(count,0,sizeof(count));
        for(int i=0;i<s.size();i++){
            count[s[i]]++;
        }
        for(int i=0;i<s.size();i++){
            if(count[s[i]]==1)return i;
        }
        return -1;
    }
};

9.——LCR 169. 招式拆解 II

class Solution {
public:
    char dismantlingAction(string arr) {
        int count[256]={0};
        for(int i=0;i<arr.size();i++){
            count[arr[i]]++;
        }
        for(int i=0;i<arr.size();i++){
            if(count[arr[i]]==1)return arr[i];
        }
        return ' ';
    }
};

10.——1624. 两个相同字符之间的最长子字符串

class Solution {
public:
    int maxLengthBetweenEqualCharacters(string s) {
        int count[256];
        int max=-1;
        memset(count,-1,sizeof(count));
        for(int i=0;i<s.size();i++){
            if(count[s[i]]==-1)count[s[i]]=i;//标记这个字符出现的位置下标
            else{
                int x=i-count[s[i]]-1;//用当前下标减去上一次出现的下标再减一
                if(max<x)max=x;
            } 
        }
        if(max>=0)return max;
        else return -1;
    }
};

11.——1512. 好数对的数目

class Solution {
public:
    int numIdenticalPairs(vector<int>& nums) {
        unordered_map<int,int>count;
        int sum=0;
        for(int i=0;i<nums.size();i++){
            sum+=count[nums[i]];
            count[nums[i]]++;
        }
        return sum;
    }
};

12.——961. 在长度 2N 的数组中找出重复 N 次的元素

class Solution {
public:
    int repeatedNTimes(vector<int>& nums) {
        unordered_map<int,int>count;
        for(int i=0;i<nums.size();i++){
            count[nums[i]]++;
        }
        for(int i=0;i<nums.size();i++){
            if(count[nums[i]]>=nums.size()/2)return nums[i];
        }
        return 0;
    }
};

13.——1207. 独一无二的出现次数

class Solution {
public:
    bool uniqueOccurrences(vector<int>& arr) {
        unordered_map<int,int>count;
        for(int i=0;i<arr.size();i++){
            count[arr[i]]++;//记录每个元素出现的次数
        }
        unordered_map<int,int>hash;
        for(int i=0;i<arr.size();i++){
            int x=count[arr[i]];//用出现的次数当键
            if(hash.find(x)==hash.end())hash[x]=arr[i];//如果出现的次数在hash没找到就把x的键标记的值为当前元素
            else{//如果找到了,判断等不等于当前遍历的元素,如果不等于就说明这个数的出现次数不是独一无二
                if(hash[x]!=arr[i])return false;
            }
        }
        return true;
    }
};

14.——2150. 找出数组中的所有孤独数字

class Solution {
public:
    vector<int> findLonely(vector<int>& nums) {
        vector<int>ret;
        unordered_map<int,int>count;
        for(int i=0;i<nums.size();i++){
            count[nums[i]]++;
        }
        for(int i=0;i<nums.size();i++){
            int x=nums[i];
            if(count.find(x-1)==count.end()&&count.find(x+1)==count.end()){
                if(count[x]==1)ret.push_back(x);
            }
        }
        return ret;
    }
};

15.——面试题 16.02. 单词频率

class WordsFrequency {
    unordered_map<string,int>hash;
public:
    WordsFrequency(vector<string>& book) {
        for(int i=0;i<book.size();i++){
            hash[book[i]]++;
        }
    }
    
    int get(string word) {
        return hash[word];
    }
};

/**
 * Your WordsFrequency object will be instantiated and called as such:
 * WordsFrequency* obj = new WordsFrequency(book);
 * int param_1 = obj->get(word);
 */

16.——1854. 人口最多的年份

class Solution {
public:
    int maximumPopulation(vector<vector<int>>& logs) {
        int hash[2051]={0};
        for(int i=0;i<logs.size();i++){
            int b=logs[i][0];
            int d=logs[i][1]-1;
            for(int j=b;j<=d;j++){
                hash[j]++;
            }
        }
        int max=1950;
        for(int i=1950;i<=2050;i++){
            if(hash[max]<hash[i]) max=i;
        }
        return max;
    }
};

17.——1742. 盒子中小球的最大数量

class Solution {
public:
    int countBalls(int lowLimit, int highLimit) {
        int count[46]={0};//注意提示1 <= lowLimit <= highLimit <= 100000,每个小球每一位最大值为9,最多5位,5*9=45
        int max=-1;
        for(int i=lowLimit;i<=highLimit;i++){
            int x=i;
            int sum=0;
            while(x){
                sum+=x%10;
                x/=10;
            }
            count[sum]++;
        }
        for(int i=1;i<=45;i++){
            if(count[i]>max)max=count[i];
        }
        return max;
    }
};

18.——2744. 最大字符串配对数目

class Solution {
public:
    int maximumNumberOfStringPairs(vector<string>& words) {
        unordered_map<string,int>cnt;
        int ans=0;
        for(int i=0;i<words.size();i++){
            string&s=words[i];
            ans+=cnt[s];            //哈希表的元素查找
            cnt[s]--;               //哈希表的元素删除
            reverse(s.begin(), s.end());
            cnt[s]++;               //哈希表的元素插入
        }
        return ans;
    }
};

19.——3146. 两个字符串的排列差

class Solution {
public:
    int findPermutationDifference(string s, string t) {
        int hash[256];
        memset(hash,-1,sizeof(hash));
        for(int i=0;i<s.size();i++){
            hash[s[i]]=i;//用哈希表标记每个字符的位置
        }
        int ans=0;
        for(int i=0;i<t.size();i++){
            ans+=abs(i-hash[t[i]]);
        }
        return ans;
    }
};

20.——2965. 找出缺失和重复的数字

class Solution {
public:
    vector<int> findMissingAndRepeatedValues(vector<vector<int>>& grid) {
        int hash[2501]={0};
        for(int i=0;i<grid.size();i++){
            for(int j=0;j<grid[i].size();j++){
                hash[grid[i][j]]++;
            }
        }
        int n=grid.size();
        vector<int>ans;
        for(int i=1;i<=n*n;i++){
            if(hash[i]==2)ans.push_back(i);
        }
        for(int i=1;i<=n*n;i++){
            if(hash[i]==0)ans.push_back(i);
        }
        return ans;
    }
};

21.——1832. 判断句子是否为全字母句

class Solution {
public:
    bool checkIfPangram(string sentence) {
        int hash[256]={0};
        for(int i=0;i<sentence.size();i++){
            char c=sentence[i];
            hash[c]=1;
        }
        for(int i='a';i<='z';i++){
            if(hash[i]==0)return false;
        }
        return true;
    }
};

22.——2351. 第一个出现两次的字母

class Solution {
public:
    char repeatedCharacter(string s) {
        int hash[256]={0};
        for(int i=0;i<s.size();i++){
            char c=s[i];
            hash[c]++;
            if(hash[c]==2)return c;
        }
        return 'a';
    }
};

23.——2670. 找出不同元素数目差数组

class Solution {
public:
    vector<int> distinctDifferenceArray(vector<int>& nums) {
        unordered_map<int,int>hash;
        vector<int>ans;
        for(int i=0;i<nums.size();i++){
            hash[nums[i]]=1;
            ans.push_back(hash.size());//每个元素前缀不同元素的数目
        }
        hash.clear();
        for(int i=nums.size()-1;i>=1;i--){
            hash[nums[i]]=1;
            ans[i-1]-=hash.size();//hash.size()代表后缀不同元素的数目,ans[i]这个值不用改,好好理解
        }
        return ans;
    }
};

24.——3159. 查询数组中元素的出现位置

class Solution {
public:
    vector<int> occurrencesOfElement(vector<int>& nums, vector<int>& queries, int x) {
        int pos[100001];
        int cnt=0;
        memset(pos,-1,sizeof(pos));//先全部初始化为-1
        for(int i=0;i<nums.size();i++){
            if(nums[i]==x){
                pos[++cnt]=i;//第cnt个x出现的位置
            }
        }
        vector<int>ans;
        for(int i=0;i<queries.size();i++){
            int y=queries[i];
            ans.push_back(pos[y]);//用结果数组记录下标,不满足条件的还是-1
        }
        return ans;
    }
};

结语

通过这二十多道的练习题相信大家对哈希表的应用有了更深刻的理解,那么初级数据结构到这就完结撒花了,非常感谢大家的观看,我们下期一起来学习有关图论的算法,从下期以后开始我们所学习的能容越来越难理解了,希望大家理解好初级数据结构,有关图论的算法有如Dijkstra算法、Bellman-Ford算法等。我们下期不见不散,拜拜。

在这里插入图片描述

关注我让我们一起学习编程,希望大家能点赞关注支持一下,让我有持续更新的动力,谢谢大家
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值