代码随想录Day6 | 哈希表理论基础 242.有效的字母异位词349. 两个数组的交集 202. 快乐数1. 两数之和

代码随想录Day6 | 哈希表理论基础 242.有效的字母异位词349. 两个数组的交集 202. 快乐数1. 两数之和

  • 哈希表基础
    • 哈希函数和哈希碰撞
    • 三种哈希结构
  • 有效的字母异位词
  • 两个数组的交集
  • 快乐数
  • 两数之和

哈希表基础

哈希表是根据关键码的值而直接进行访问的数据结构
其作用:判断一个元素是否出现在集合里

哈希函数和哈希碰撞

将一段数据映射到哈希表上的处理方法,但对于一个数组来说,其长度是有限的,如果数据元素个数大于其长度,会产生不同数据出现在统一索引位置这就是哈希碰撞。
哈希碰撞的解决方法:拉链法和线性检测法

  1. 拉链法:将冲突的元素存储在链表中,链表的起点就是被冲突的索引地址
  2. 线性探测法:哈希表的容量大于数据个数,利用冲突位置的下一个空位置来存放冲突元素。

三种哈希结构

  1. 数组
    对于映射长度可控的可以使用,比如英文字母
  2. set集合
    代码随想录
    代码随想录Day6 | 哈希表理论基础 242.有效的字母异位词349. 两个数组的交集 202. 快乐数1. 两数之和_第1张图片
  3. map映射
    代码随想录
    代码随想录Day6 | 哈希表理论基础 242.有效的字母异位词349. 两个数组的交集 202. 快乐数1. 两数之和_第2张图片
  4. 使用场景
    优先使用unordered_set,利用其较好的查找删除效率,如果要求集合是有序的那么可以利用set,如果集合中需要存在重复数据那么就利用multiset

有效的字母异位词

文档讲解:代码随想录
视频讲解: 学透哈希表,数组使用有技巧!Leetcode:242.有效的字母异位词
状态:×

  1. 思路
    由于对于小写字母来说,只有26个,所以可以利用数组来充当哈希表,那么如何构造哈希函数–将字母变为数字下标,利用字母的ASCII码值即可,char-‘a’。
    遍历s的时候对下标对应的值进行+1操作,在遍历t的时候对下标对应的值进行-1操作。
    最后的检测就是数组中的数据是否全为0。
class Solution {
public:
    bool isAnagram(string s, string t) {
        vector check(26,0);
        for(int i = 0;i

时间复杂度: O ( 3 n ) O(3n) O(3n)

两个数组的交集

文档讲解:代码随想录
视频讲解: 学透哈希表,set使用有技巧!Leetcode:349. 两个数组的交集
状态:可以用数组,不会set

  1. 数组思路
    与上一题类似,因为元素的个数最多是1001个,所以可以考虑使用数组。那么就i需要自己构建哈希函数,我们将元素值作为哈希表的索引值即可。
    但这道题还需要考虑一些情况,因为这道题是需要找出相同的数,并且不重复的输出。
    那么上一道题利用等于一个val的判断就不适用了,因为初始化哈希数组,会将所有元素变为这个val。第二点是不重复,如果我们在第一数组进行映射的时候还是将索引对应的值++,那么最后判断的时候会出现重复,或者避免了重复会出现结果为空,比如nums2中只有1个值,而nums1中有多个。
    所以做法是,每次映射值的时候将索引对应的值变为1,然后找到值进行–操作,这样当哈希数组中的值变为0的时候,那说明存在相交,且这个值只会被加入一次,因为之后再存在就是负数了。
    对于避免加入本来就不存在数的情况,将返回数组的更新放在检查第二个数组的循环里面进行。
    具体代码如下
class Solution {
public:
    vector intersection(vector& nums1, vector& nums2) {
        vector res;
        vector check(1001);

        for(int i = 0;i
  1. 哈希表思路
    对于不重复且不排序就考虑使用unordered_set<>
//定义哈希表
unordered_set Name;
//定义同时赋值
unordered_set Name(list1.begin(),list1.end());
//查找元素是否出现
Name.find(num) != Name.end() //当num对应的位置不是最后一个说明存在
//插入元素
Name.insert(num);

本题的具体代码

class Solution {
public:
    vector intersection(vector& nums1, vector& nums2) {
        unordered_set res;//用于去重
        unordered_set check(nums1.begin(),nums1.end());//用于存储检测

        for(int num:nums2)
        {
            if(check.find(num) != check.end())
            {
                res.insert(num);
            }
        }

        return vector(res.begin(),res.end());
    }
};

快乐数

文档讲解:代码随想录
视频讲解:
状态:×

  1. 思路
    无限循环说明会有重复的结果出现,可以考虑使用哈希表,n比较大所以使用数组不再合适,使用unordered_set当之后出现的数在set里面发现,那么就可以返回false并终止循环。
    本题代码如下
class Solution {
public:
    bool isHappy(int n) {
        //无限循环说明会有重复
        unordered_set check;
        
        while(1)
        {
            //每次开始循环之前初始化平方和结果
            int final = 0;

            //计算平方和结果
            while(n)
            {
                
                final += (n%10)*(n%10);
                n = n/10;
            }
            //将平方和结果变为下一次循环的n
            n = final;
            
            //当平方和结果为1 返回true跳出循环
            if(final == 1)
            {
                return true;
                break;
            }
            
            //当平方和结果之前存在,返回false跳出循环
            if(check.find(final) != check.end())
            {
                return false;
                break;
            }
            //当平方和结果不为1,且不存在添加到set中
            else
            {
                check.insert(final);
            }
        }
    }
};

时间复杂度: O ( l o g n ∗ 1 ) O(logn * 1) O(logn1) logn是求平方和的时间

两数之和

文档讲解:代码随想录
视频讲解: 梦开始的地方,Leetcode:1.两数之和,学透哈希表,map使用有技巧!
状态:只会暴力

  1. 思路
    不重复出现,说明我们需要利用unordered来存放满足条件的值。
    返回下标,不是返回值,说明我们需要存放一个类似字典的数据(val,index)
    所以考虑使用map
//返回一个数组
return {a,b};

//map的一些操作
//定义
unordered_map check;
//定义查找的变量利用auto pair
auto i= check.find(target);
//pair第一个数据存放的是我们的target,第二个数据存放的是我们的下标,map去find的时候,是去搜寻第一个值,所以第一个值应当为我们的target
//获取方式
i->first;
i->second;
//插入一组数据,与查询相对应
check.insert(pair(nums[i),i);

本题代码如下

class Solution {
public:
    vector twoSum(vector& nums, int target) {
        unordered_map check;
        for(int i = 0;isecond};
            }
            else
            {
                check.insert(pair(nums[i], i));
            }
        }
        return {};
    }
};

你可能感兴趣的:(数据结构)