首页 > 编程语言 >代码随想录算法训练营第五天|LeetCode242.有效的字母异位词 LeetCode 349. 两个数组的交集 LeetCode202. 快乐数 LeetCode 1. 两数之和

代码随想录算法训练营第五天|LeetCode242.有效的字母异位词 LeetCode 349. 两个数组的交集 LeetCode202. 快乐数 LeetCode 1. 两数之和

时间:2024-07-08 17:29:09浏览次数:18  
标签:set 哈希 nums sum 随想录 unordered 数组 LeetCode 两数

代码随想录算法训练营

Day5 代码随想录|LeetCode242.有效的字母异位词 LeetCode 349. 两个数组的交集 LeetCode202. 快乐数 LeetCode 1. 两数之和


文章目录


前言

代码随想录原文–哈希表
今天的内容真的很有挑战o(╥﹏╥)o,做了很久

一、哈希表基础理论

1、定义

哈希表是根据关键码的值而直接进行访问的数据结构

2、概念

(1)哈希函数:把数据直接映射为哈希表上的索引,然后就可以通过查询索引下标快速确定某个数据是否出现过
哈希函数示意图
哈希函数示意图
(2)哈希碰撞:将不同数据映射到同一索引
解决哈希碰撞
1)拉链法:用链表存放映射到同一索引的不同数据
拉链法示意图
拉链法示意图
2)线性探测法
使用线性探测法,一定要保证哈希表大小大于数据个数。
AB发生哈希冲突在冲突的位置放A,那么就向下找一个空位放置B
线性探测法示意图
线性探测法示意图

3、哈希表实现的三种方法

(1)数组:
1)数组索引作为哈希值,数组值存放答案
2)适合哈希值范围明确的情况
3)数组的大小是受限制的,而且如果元素很少,而哈希值太大会造成内存空间的浪费。
(2)集合:
1)集合索引作为哈希值,集合元素存放答案
2)适合哈希值不明确的情况,根据对顺序、是否重复的要求选择三种不同的集合

名称特点
unordered_set无序、无重复,优先使用unordered_set
set有序、无重复
multiset有序,有重复

3)里面放的元素只能是一个值
(3)映射map
1)映射键作为需要进行查找的值(可以认为是哈希值),映射值存放另一个要保存的值
2)适合需要保存的值和进行比较的值不一样的情况

名称特点
unordered_mapkey无序、key无重复,优先使用unordered_map
mapkey有序、key无重复
multimapkey有序,key有重复

4、哈希表适合的问题

确定元素是否在某一集合中出现

二、LeetCode242.有效的字母异位词

1.题目链接

LeetCode242.有效的字母异位词

2、思路

(1)用字母的ASCII码求哈希值,这样至多有26个哈希值,所以可以用数组实现哈希表
(2)哈希值=ASCII码-‘a’,由于都是小写,a-z对应0-25
(3)先比较字符串长度,长度不同的字符串一定不符合条件
(4)接下来遍历两个字符串,s中的字母出现时,哈希表中字母对应的值+1,t中字母出现时,哈希表中字母对应的值-1
(5)最后遍历哈希表,若哈希表中有元素非零,那么说明一定是某个字母在两个字符串出现次数不同

3、题解

class Solution {
public:
    bool isAnagram(string s, string t) {
        int ans[26]={0};
        int lens=s.size();
        int lent=t.size();
        if(lens!=lent)return 0;
        for(int i=0;i<lens;i++)
        {
            ans[s[i]-'a']++;
            ans[t[i]-'a']--;
        }
        for(int i=0;i<26;i++)
        {
            if(ans[i])return 0;
        }
        return 1;
    }
};

三、LeetCode 349. 两个数组的交集

1、题目链接

LeetCode 349. 两个数组的交集

2、思路

(1)这道题在题干添加范围条件之前,适合用set来做,为了练习set实现哈希表,这里用了集合而非数组,其实用数组更简单
(2)选择unordered_set是因为无序、无重复
避免排序造成的浪费
(3)用unordered_set构造哈希表存放其中一个数组,这里选择存放nums1,一次判断nums2中的元素是否在其中,若是,则插入res集合
(4)最后将res集合变成数组,之所以不一开始就用数组存放答案,是为了利用unordered_set无重复的特性自动去重

3、题解

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        unordered_set <int> nums(nums1.begin(),nums1.end());
        unordered_set <int>res;
        int s=nums2.size();
        for(int i=0;i<s;i++)
        {
            if(nums.find(nums2[i])!=nums.end())
            {
                res.insert(nums2[i]);
            }
        }
        vector<int> ans(res.begin(),res.end());
        return ans;
    }
};

四、 LeetCode202. 快乐数

1、题目链接

LeetCode202. 快乐数

2、思路

(1)这道题更难的部分是判断出平方和不为1,一直循环的情况,我们要思考无限循环的情况的特征
(2)发现无限循环就是同样的平方和重复出现
(3)用集合构造哈希表,存放已经出现过的平方和
(4)求平方和,并判断:
1)如果平方和为1 返回true
2)平方和在哈希表中能找到 返回false
3)其他情况继续计算
(5)这里我用递归实现,如果感觉递归麻烦,可以用while(1)
为什么用集合:
1、简化查询操作
2、自动去重

3、题解

(1)递归

class Solution {
public:
    unordered_set<int> sum;
    bool isHappy(int n) {
       int s=0;
        while(n)
        {
            s+=(n%10)*(n%10);
            n/=10;
        }
        if(s==1)return 1;
        if(sum.find(s)!=sum.end())return 0;
        sum.insert(s);
        return isHappy(s);

    }
};

(2)迭代

class Solution {
public:
    unordered_set<int> sum;
    bool isHappy(int n) {
        while(1)
        {
            int s=0;
            while(n)
           {
                s+=(n%10)*(n%10);
                n/=10;
           }
            if(s==1)return 1;
            if(sum.find(s)!=sum.end())return 0;
            sum.insert(s);
            n=s;
         }
    }
};

五、LeetCode 1. 两数之和

1、题目链接

LeetCode 1. 两数之和

2、思路

(1)总体思路:遍历nums所有元素,将如果元素x前面有 y=target-x 出现,那么说明找到答案
(2)用映射实现哈希表
1)为什么用哈希表:希望存放遍历过的nums元素并去重
2)为什么不用数组:不确定哈希值范围
3)为什么用映射不用集合:最后要输出元素在nums的下标,而两数之和这道题目要返回x 和 y的下标,不仅要判断y=target-x是否存在而且还要记录y的下标位置,所以set 也不能用
4)键值分别代表什么:
由于我们想要每个元素都不重复出现,而且根据元素进行查询,而map的查询是根据键进行的,所以键是nums元素,值是nums索引,根据键可以找到值

3、题解

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        unordered_map <int,int> map;
        vector <int> ans;
        for(int i=0;i<nums.size();i++)
        {
            auto iter=map.find(target-nums[i]);
            if(iter!=map.end())
            {
                ans.push_back(iter->second);
                ans.push_back(i);
                return ans;
            }
            map.insert(pair<int,int>(nums[i],i));
        }
        return ans;
    }
};

总结

1、哈希表方便在哪里:简化查询操作
例如查找某个元素X是否出现在A中,若A为集合,A.find(X)!=A.end()就表示X出现在A中
并且集合可以自动去重

2、集合的常用语法
(1)创建

unordered_set<int> sum;

(2)初始化
用数组初始化(数组变集合)

unordered_set <int> nums(nums1.begin(),nums1.end());

(3)是否出现

sum.find(s)!=sum.end()//表示s在sum中出现

3、实现哈希表的三种数据结构
(1)数组:
1)数组索引作为哈希值,数组值存放答案
2)适合哈希值范围明确的情况
3)数组的大小是受限制的,而且如果元素很少,而哈希值太大会造成内存空间的浪费。
(2)集合:
1)集合索引作为哈希值,集合元素存放答案
2)适合哈希值不明确的情况,根据对顺序、是否重复的要求选择三种不同的集合

名称特点
unordered_set无序、无重复,优先使用unordered_set
set有序、无重复
multiset有序,有重复

3)里面放的元素只能是一个值
(3)映射map
1)映射键作为需要进行查找的值(可以认为是哈希值),映射值存放另一个要保存的值
2)适合需要保存的值和进行比较的值不一样的情况

名称特点
unordered_mapkey无序、key无重复,优先使用unordered_map
mapkey有序、key无重复
multimapkey有序,key有重复
4、map的常用语法
1)创建
unordered_map<int> sum;

(2)插入

map.insert(pair<int,int>(nums[i],i));

(3)是否出现

auto iter=map.find(target-nums[i]);//返回迭代器,表示键对应的对象的地址
iter!=map.end();//表示s在sum中出现

iter->second是键对应的值

标签:set,哈希,nums,sum,随想录,unordered,数组,LeetCode,两数
From: https://blog.csdn.net/2301_79647020/article/details/140265587

相关文章

  • 代码随想录算法训联营第四天|LeetCode24. 两两交换链表中的节点 LeetCode19.删除链表
    系列文章目录代码随想录算法训练营第四天:代码随想录|LeetCode24.两两交换链表中的节点LeetCode19.删除链表的倒数第N个节点面试题02.07.链表相交LeetC142.环形链表文章目录系列文章目录前言一、LeetCode24.两两交换链表中的节点1、题目链接2、题解二、LeetCod......
  • LeetCode 523. 连续的子数组和
    523.连续的子数组和给你一个整数数组 nums 和一个整数 k ,如果 nums 有一个 好的子数组 返回 true ,否则返回 false:一个 好的子数组 是:长度 至少为2 ,且子数组元素总和为 k 的倍数。注意:子数组 是数组中 连续 的部分。如果存在一个整数 n ,令整数 x......
  • LeetCode 974. 和可被 K 整除的子数组
    974.和可被K整除的子数组给定一个整数数组 nums 和一个整数 k ,返回其中元素之和可被 k 整除的非空 子数组 的数目。子数组 是数组中 连续 的部分。示例1:输入:nums=[4,5,0,-2,-3,1],k=5输出:7解释:有7个子数组满足其元素之和可被k=5整除:[4,5,0......
  • 「代码随想录算法训练营」第五天 | 哈希表 part1
    242.有效的字母异位词题目链接:https://leetcode.cn/problems/valid-anagram/题目难度:简单文章讲解:https://programmercarl.com/0242.有效的字母异位词.html视频讲解:https://www.bilibili.com/video/BV1YG411p7BA题目状态:一次过,哈哈哈个人思路:之前在《剑指offer》中做过......
  • 代码随想录算法训练营第25天 | 491.递增子序列
    491.递增子序列给定一个整型数组,你的任务是找到所有该数组的递增子序列,递增子序列的长度至少是2。示例:输入:[4,6,7,7]输出:[[4,6],[4,7],[4,6,7],[4,6,7,7],[6,7],[6,7,7],[7,7],[4,7,7]]说明:给定数组的长度不会超过15。数组中的整数范围是[-10......
  • [LeetCode] 134. Gas Station
    想到了提前判断和小于0的情况,懒得写,果然被阴间用例10万个加油站坑了。classSolution:defcanCompleteCircuit(self,gas:List[int],cost:List[int])->int:#1n=len(gas)ifn==1:ifgas[0]>=cost[0]:ret......
  • 代码随想录算法训练营第56天 | 42. 接雨水 、84.柱状图中最大的矩形
    图论理论基础大家可以在看图论理论基础的时候,很多内容看不懂,例如也不知道看完之后还是不知道邻接矩阵,邻接表怎么用,别着急。理论基础大家先对各个概念有个印象就好,后面在刷题的过程中,每个知识点都会得到巩固。https://www.programmercarl.com/kamacoder/图论理论基础.html......
  • LeetCode 算法:岛屿数量 c++
    原题链接......
  • [LeetCode] 238. Product of Array Except Self
    坑真的很多,首先要处理全零reduce没有值typeerror的问题。classSolution:defproductExceptSelf(self,nums:List[int])->List[int]:total=reduce(mul,nums)ret=[]iftotal==0:try:total=reduce(mul,[......
  • 刷爆leetcode第九期
    题目一单值二叉树如果二叉树每个节点都具有相同的值,那么该二叉树就是单值二叉树。只有给定的树是单值二叉树时,才返回true;否则返回false。题目图片如下我们这里主要是判断下根的值和它的左孩子还有右孩子相不相等如果相等返回true如果不相等返回false(当然这里还需要......