五月集训 (第07天) —— 哈希表

Posted 英雄哪里出来

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了五月集训 (第07天) —— 哈希表相关的知识,希望对你有一定的参考价值。

文章目录

前言

        此为《英雄算法联盟:算法集训》的内容,具体内容详见:知识星球:英雄算法联盟。加入星球后,即可享用星主 CSDN付费专栏 免费阅读 的权益。
        欢迎大家积极在评论区留言发表自己的看法,知无不言,言无不尽,养成每天刷题的习惯,也可以自己发布优质的解题报告,供社区一同鉴赏,吸引一波自己的核心粉丝。
        希望大家先自己思考,如果实在没有想法,再看下面的算法思路,如果有思路但是写不出来,可以参考朋友圈中其他人的代码,总有一款是适合你的,关注一下他,取其之长,补给之短。
        今天集训的内容是:哈希表
        前三题较为简单,最后一题用C++会非常方便,如果暂时写不出来,可以先记录下,后续再来做。

一、练习题目

题目链接难度
1512. 好数对的数目★☆☆☆☆
2006. 差的绝对值为 K 的数对数目★☆☆☆☆
1347. 制造字母异位词的最小步骤数★★☆☆☆
面试题 10.02. 变位词组★★☆☆☆

二、算法思路

1、好数对的数目

        (1)假设有一种容器,我们可以枚举一个 j,容器里面放的是所有 [0, j-1] 的数字的计数;
        (2)当我们执行查找的时候,能够快速找到这个数,并且将它进行统计;而且插入也能达到理想时间复杂度,这件事情就变得简单了。
        (3)符合这两个操作的容器,就是哈希表。

int numIdenticalPairs(int* nums, int numsSize)
    int j, ans = 0;
    int hash[101];
    memset(hash, 0, sizeof(hash));
    for(j = 0; j < numsSize; ++j) 
        ans += hash[  nums[j] ];   // 查找
        ++ hash[ nums[j] ];        // 插入
    
    return ans;

2、差的绝对值为 K 的数对数目

        (1)和第一题类似,我们可以将 |nums[i] - nums[j]| == k 转换成两个式子
                (1.1)nums[i] == nums[j] + k
                (1.2)nums[i] == nums[j] - k
        (2)定义一个哈希表,同样枚举 j,分别查找 nums[j] + knums[j] - k 是否在哈希表中,并且累加计数;
        (3)然后,将 nums[j] 插入哈希表;

int countKDifference(int* nums, int numsSize, int k)
    int hash[101];
    int ans = 0;
    memset(hash, 0, sizeof(hash));

    for(int j = 0; j < numsSize; ++j) 
        int x = nums[j] + k;
        if(x >= 1 && x <= 100) 
            ans += hash[x];
        
        x = nums[j] - k;
        if(x >= 1 && x <= 100) 
            ans += hash[x];
        
        ++hash[ nums[j] ];
    
    return ans;

3、制造字母异位词的最小步骤数

        (1)因为只有小写字母,所以遇到这个问题,直接用两个哈希表分别映射两个字符串;
        (2)枚举每个字母,对两个哈希表对应字母数量进行差值,当差值为负数,则累加,最后返回这个答案。

int minSteps(char * s, char * t)
    int ans = 0, i;
    int hashs[256], hasht[256];
    memset(hashs, 0, sizeof(hashs));
    memset(hasht, 0, sizeof(hasht));
    for(i = 0; s[i]; ++i) 
        ++hashs[ s[i] ];
        ++hasht[ t[i] ];
    
    for(i = 'a'; i <= 'z'; ++i) 
        int x = hashs[i] - hasht[i];
        if(x > 0) 
            ans += x;
        
    
    return ans;

4、变位词组

        (1)定义一个字符串到字符串数组的哈希表映射(可以用 c++ 中的 unordered_map <string, vector<string>>
        (2)对于每个字符串,按照某种规则排序(比如字典序排序),然后插入到哈希表中;
        (3)遍历哈希表,将它展平成一个二维数组;

class Solution 
    unordered_map <string, vector<string>> ans;
public:
    vector<vector<string>> groupAnagrams(vector<string>& strs) 
        vector<vector<string>> ret;
        for(int i = 0; i < strs.size(); ++i) 
            string s = strs[i];
            sort(s.begin(), s.end());
            ans[s].push_back(strs[i]);
        
        for(const auto& v : ans) 
            ret.push_back( v.second );
        
        return ret;
    
;

以上是关于五月集训 (第07天) —— 哈希表的主要内容,如果未能解决你的问题,请参考以下文章

六月集训(第07天) —— 哈希表

五月集训 (第08天) —— 前缀和

五月集训(第22天) —— 有序集合

七月集訓(第07天) —— 哈希表

七月集訓(第07天) —— 哈希表

五月集训(第13天) —— 双向链表