代码随想录算法训练营第五天|242.有效的字母异位词,349.两个数组的交集,202.快乐数,1.两数之和
2026/7/22 8:59:38 网站建设 项目流程

242.有效的字母异位词

看到题目的第一想法

题目的意思就是说,给两个字符串,判断两个字符串里面的相同字母个数是不是一样的。那我遍历我的第一个字符串,记录下它的字母个数,然后再遍历我第二个字符串,记下它字母个数,一比较就OK了。

看完代码随想录的第一想法

遍历字符串的想法是正确的,但是我缺少了如何记录字母个数的方法。用上哈希表的话,确实就能记录字母的个数。这里有两个很妙的点,第一个就是能把数组当做哈希表来使用。第二个就是通过将字符串遍历出来的字母减去字符串a就能得到0至25中的任意一个数,再以这个数作为数组的地址,变化的值作为数组的值。这样就能精准地26个字母的数量。

用自己的话描述

首先设置一个26位的数组a。开始遍历第一个字符串,字符串遍历出来的字母减去字符串a,就能得到0~25中的任意一个数num1,在数组a中的num位置加1。直到将第一个字符串遍历完成,开始遍历第二个字符串,用同样的方法得到num2,在数组a中num2的位置进行减1。最后遍历这个数组a,如果其中有一项不为0,就return false,否则return true

代码
classSolution{publicbooleanisAnagram(Strings,Stringt){//首先设置一个26位的数组a。int[]a=newint[26];//开始遍历第一个字符串,字符串遍历出来的字母减去字符串a,就能得到0~25中的任意一个数num1,//在数组a中的num位置加1。直到将第一个字符串遍历完成,for(inti=0;i<s.length();i++){a[s.charAt(i)-'a']++;}//开始遍历第二个字符串,用同样的方法得到num2,在数组a中num2的位置进行减1。for(inti=0;i<t.length();i++){a[t.charAt(i)-'a']--;}//最后遍历这个数组a,如果其中有一项不为0,就return false,否则return truefor(intcount:a){if(count!=0){returnfalse;}}returntrue;}}

实现过程中遇到哪些困难

思路通了之后,就没有遇到什么困难了。

今日收获,记录一下自己的学习时长

第一个收获:能把数组当做哈希表来使用。第二个收获:字母减去字符串 a,就能得到这个字母是在字母表中的第几个数。以此可以去创作一个数组版的字母表。大概一个小时


349.两个数组的交集

看到题目的第一想法

题目的意思就是说,给两个数组,看看他们之中的交集。输出这个交集的数组。看到这一题,我就想着和上一题差不多思路的写法。将这两个数组的数字都存到两个新的数组a,b中以数字为地址,值存数字的个数。然后再遍历两个数组a,b。如果同时都不为零。将这个数组的地址存入另一个新数组c中。最后输出新数组c。

看完代码随想录的第一想法

1.用数组来做哈希的题目,都是因为题目限制了数值的大小。而且如果哈希值比较少、特别分散、跨度非常大,使用数组就造成空间的极大浪费。(本题后面 力扣改了 题目描述 和 后台测试数据,增添了 数值范围:1 <= nums1.length, nums2.length <= 1000,0 <= nums1[i], nums2[i] <= 1000,所以就可以 使用数组来做哈希表了, 因为数组都是 1000以内的。)

2.这一题主要是学会使用一种哈希数据结构:unordered_set,要留意题目说明:输出结果中的每个元素一定是唯一的,也就是说输出的结果的去重的, 同时可以不考虑输出结果的顺序

版本一:使用HashSet
用自己的话描述

先是创建两个哈希集合set1,reset。set1用于记录num1的内容并去重,reset用于记录set1和num2的交集。遍历数组num2同时问set1中是否存在,如果存在就加入reset中。另外申请一个数组存放reset中的元素,最后返回数组

代码
classSolution{publicint[]intersection(int[]nums1,int[]nums2){//忘记处理边界值,要创建一个空数组,必须明确指定长度或显式提供初始化元素,new int[0]或new int[] {}if(nums1==null||nums1.length==0||nums2==null||nums2.length==0){returnnewint[0];}//先是创建两个哈希集合set1,reset。//set1用于记录num1的内容并去重,reset用于记录set1和num2的交集Set<Integer>set1=newHashSet<>();Set<Integer>reSet=newHashSet<>();//遍历数组num1for(inti:nums1){set1.add(i);}//遍历数组num2同时问set1中是否存在,如果存在就加入reset中for(inti:nums2){if(set1.contains(i)){reSet.add(i);}}//方法1:将结果集合转成数组/** * 将 Set<Integer> 转换为 int[] 数组: * 1. stream() : Collection 接口的方法,将集合转换为 Stream<Integer> * 2. mapToInt(Integer::intValue) : * - 中间操作,将 Stream<Integer> 转换为 IntStream * - 使用方法引用 Integer::intValue,将 Integer 对象拆箱为 int 基本类型 * 3. toArray() : 终端操作,将 IntStream 转换为 int[] 数组。 */returnreSet.stream().mapToInt(Integer::intValue).toArray();//方法2:另外申请一个数组存放reset中的元素,最后返回数组int[]arr=newint[reSet.size()];intj=0;for(inti:reSet){arr[j++]=i;}returnarr;}}
版本二:使用Hash数组
用自己的话描述

将这两个数组的数字都存到两个新的数组a,b中以数字为地址,值存数字的个数。然后再遍历两个数组a,b。如果同时都不为零。将这个数组的地址存入另一个新动态数组c中。

代码
classSolution{publicint[]intersection(int[]nums1,int[]nums2){//将这两个数组的数字都存到两个新的数组a,b中以数字为地址,值存数字的个数。int[]a=newint[1024];int[]b=newint[1024];for(inti:nums1){a[i]++;}for(inti:nums2){b[i]++;}//然后再遍历两个数组a,b。如果同时都不为零。将这个数组的地址存入另一个新动态数组c中。List<Integer>c=newArrayList<>();for(inti=0;i<1024;i++){if(a[i]>0&&b[i]>0){c.add(i);}}//方法1:将结果动态数组c转成数组// return c.stream().mapToInt(Integer :: intValue).toArray();//方法2:另外申请一个数组存放动态数组c中的元素,最后返回数组int[]arr=newint[c.size()];intj=0;for(inti:c){arr[j++]=i;}returnarr;}}

实现过程中遇到哪些困难

没有遇到什么困难

今日收获,记录一下自己的学习时长

学会了return c.stream().mapToInt(Integer :: intValue).toArray();快速将Integer类型的值快速拆为int类型数组。HashSet有着去重效果

202.快乐数

看到题目的第一想法

快乐数有多快乐?结果毫无头绪

看完代码随想录的第一想法

读懂题目真的挺重要的。1.理解无限循环 ->求和的过程中,sum会重复出现 2.记住这句,当我们遇到了要快速判断一个元素是否出现集合里的时候,就要考虑哈希法了

我确实是不会这一题,下面是我看完题解后的理解

用自己的话描述

首先给你个数。比如说这个数是19。题目要求你将1和9平方之后加在一起。于是得到了82。根据例子,经过两次相同计算,就会得到1。那么你就已经初步理解了题目。关键在于,不断循环下去只会有两个结果:一个是得到1,另外一个是无限循环。而无限循环的另一个理解就是得到一个过往得到的数。那么这个时候你就已经有了初步的思路。开始理清整个题目的脉络,首先这个数n = 19传了进去。n要进入循环,这个循环继续的条件就是得到n != 1,或者得到哈希集合record中没有的数!record.contains(n)。这个哈希集合一开始是没有数的,进去循环的第一步,我就要先把一开始的数n传入哈希集合record中。这样,这个哈希集合record利用它无序、不重复的特点。创造出了循环退出的条件。即是,n == 1或record.contains(n)。开始拆分19这个数字。替换循环的数n。如果这个数n不在record中,进入下一轮循环,如果record.contains(n)或者n == 1,那么就那这个n和1进行比较,如果n == 1,就返回true,如果n != 1 就返回false

代码
classSolution{publicbooleanisHappy(intn){//创建一个哈希集合用于记录不重复的数Set<Integer>record=newHashSet<>();//设置循环继续的条件为n != 1 && !record.contains(n),反之如果n == 1 || record.contains(n)while(n!=1&&!record.contains(n)){//记录不重复的数,进入哈希集合record.add(n);//将n里面的数进行拆分计算放回n里面。n=getNextNumber(n);}//n和1进行比较,如果n == 1,就返回true,如果n != 1 就返回falsereturnn==1;}privateintgetNextNumber(intn){//先设一个加起来的数intnum=0;//拆分数字要用循环while(n>0){inttemp=0;temp=n%10;num+=temp*temp;n=n/10;}returnnum;}}

实现过程中遇到哪些困难

1.对于无限循环,不能理解他隐藏的意思
2.想不到怎么使用哈希法

今日收获,记录一下自己的学习时长

1.收获了对题意的理解,对无限循环的理解也更加深刻
2.收获了对数的处理可以放到另一个函数中去。学习时长大约是1小时


1.两数之和

看到题目的第一想法

有一点思路,遍历第一个数,加上遍历第二个数,应该做个嵌套的for循环就解决了

看完代码随想录的第一想法

刚刚那个想法也是可以的,那种是属于暴力的解法。代码随想录的这个用HashMap解决的做法会跟高级一些。其原理也简单易懂。但还是有一点,要知道在什么时候用哈希法,在查看这个元素在不在集合中,一个元素有没有出现过。这个题目就属于要查看已经存入HashMap中的值,有没有需要的

用自己的话描述

就是遍历当前数组中的元素,计算出当前元素需要的目标元素,然后去HashMap中寻找,如果找到了就将当前元素和目标元素的下标存入数组res中,没找到就将当前元素存入HashMap中,key为当前元素,value为当前元素的下标。

代码
classSolution{publicint[]twoSum(int[]nums,inttarget){// 就是遍历当前数组中的元素,计算出当前元素需要的目标元素,然后去HashMap中寻找,如果找到了就将当前元素和目标元素的下标存入数组res中,没找到就将当前元素存入HashMap中,key为当前元素,value为当前元素的下标。int[]res=newint[2];Map<Integer,Integer>record=newHashMap<>();// 就是遍历当前数组中的元素for(inti=0;i<nums.length;i++){//计算出当前元素需要的目标元素inttemp=target-nums[i];// 去HashMap中寻找,如果找到了就将当前元素和目标元素的下标存入数组res中,没找到就将当前元素存入HashMap中if(record.containsKey(temp)){res[0]=record.get(temp);res[1]=i;break;}record.put(nums[i],i);}//返回当前数组resreturnres;}}

实现过程中遇到哪些困难

思路有了就没什么困难

今日收获,记录一下自己的学习时长

学习了怎么用HashMap这个数据结构。半个小时

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询