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

今日前置知识

哈希表理论基础

今日主要题目

242.有效的字母异位词

349. 两个数组的交集

202.快乐数

1. 两数之和

主要学习网址

代码随想录

做题思路与具体代码

题目一:242.有效的字母异位词

做题思路

(hash数组经典题)

本题采用hash数组来实现哈希表的作用的知识,核心点是为了找到两个字符串之间的交集重复元素

首先初始化一个数组,然后将第一个字符串每个字符映射成数组每个位置上的值++

再将第二个字符串每个字符映射成数组每个位置上的值--

因为标题中有写两个字符串每个字符出现的次数都相同

所以可以采用一加一减的方法

再判断数组里面要是全为0,就说明两个字符串包含的字符都是一样的

具体代码
class Solution {
    public boolean isAnagram(String s, String t) {
    //本题采用数组来实现哈希表的作用
    //统计字符串每个字母都放到数组上
    //初始化哈希数组
    int hash[]=new int[26];
    //统计s上的字母数++
    for(int i=0;i<s.length();i++){
        hash[s.charAt(i)-'a']++;
    }
    //统计t上的字母数--
    for(int i=0;i<t.length();i++){
        hash[t.charAt(i)-'a']--;
    }
    //判断hash数组上有没有不为0的数,有的话就返回false
    for(int count:hash){
        if(count!=0)return false;
    }
    //是字母异位词
    return true;
    }
}

题目二:349. 两个数组的交集

本题采用hashset或hash数组的方法都可以,因为用hashset的情况是因为值太大,数组不能取那么大的范围

做题思路一:hashset方法

初始化两个hashset分别为set1和set2,把第一个数组的值放进去set1,然后遍历第二个数组,逐一与set1中的值比较,如果既存在于set1又存在于第二个数组,就放入set2

为什么要放入set2,因为我们可能会得到多个同样的结果,放入set2可以去重

最后再用数组存储set2中的元素

具体代码
class Solution {
    public int[] intersection(int[] nums1, int[] nums2) {
    //思路一:用set,范围太大用hashset
    //初始化两个hashset,一个用来暂时存储,一个用来存并集(内部元素不重复,hashset特性)
    Set<Integer> set1=new HashSet<>();
    Set<Integer> set2=new HashSet<>();
    //遍历数组一将nums1的值放入set1
    for(int i:nums1){
        set1.add(i);
    }
    //遍历数组二判断数组二的值是否在set1中
    for(int i:nums2){
        //如果存在,放入set2中
        if(set1.contains(i)){
            set2.add(i);
        }
    }
    //将set2中的并集拿出来,放到数组中
    //初始化数组
    int result[]=new int[set2.size()];
    int n=0;
    for(int i:set2){
        result[n++]=i;
    }
    return result;
    }
}

做题思路二:hash数组方法

本题跟第一题不一样,没有说两个字符串每个字符出现的次数都相同

所以不能用一加一减的方式

分别用两个数组去存,分别都加,也就是将每个元素所对应的数组位上的数值++

然后初始化一个arraylist

同时遍历两个数组,如果在两个相同下标位置的数值都不为0,也就是两个原数组都包含该数,那么就将这个数存入arraylist

最后再将arraylist中的值存入数组中

(为什么这里要用到arraylist,因为我们放入并集的元素的个数是不确定的,而arraylist是动态数组,可以不用考虑初始容量的问题,这里要特别注意)

具体代码
class Solution {
    public int[] intersection(int[] nums1, int[] nums2) {
    //思路二:采用hash数组方法,因为里面数组的范围不是很大,才1000,如果是上万最好用hashset
    //这道题定义两个计算数组存放两个数组出现数的个数
    //然后用list存放两个计算数组的值
    int hash1[]=new int[1001];
    int hash2[]=new int[1001];
    for(int i:nums1){
        hash1[i]++;
    }
    for(int i:nums2){
        hash2[i]++;
    }
    //初始化一个list
    List<Integer> list=new ArrayList<>();
    int a=0;
    while(a<1001){
        if(hash1[a]!=0&&hash2[a]!=0){
            list.add(a);
        }
        a++;
    }
    //初始化返回数组
    int result[]=new int[list.size()];
    int n=0;
    for(int i:list){
        result[n++]=i;
    }
    return result;
    
    }
}

题目三:202.快乐数

做题思路

本题也采用HashSet思路

这个数在逐渐求平方和的时候,可能会出现无限循环的情况,所以我们用hashset来存储过程中出现的结果,直到结果为1或者是出现了之前出现过的数(无限循环),再判断最后的值是否与1相等,相等证明是快乐数,不相等证明不是

(我们要存的一直都是平方和的数,就是一直存储平方和,直到它变成1或者和之前一样了)

具体代码
class Solution {
    public boolean isHappy(int n) {
        //本题采用hashset的方式来解决无限循环的问题,如果遇到变成和之前一样的元素就立刻返回false
        //初始化hashset
        Set<Integer> set1=new HashSet<>();
        //如果元素变为1就退出或者是遇到变成和之前一样的元素就退出
        while(n!=1&&!set1.contains(n)){
        //先把数放入set1中
            set1.add(n);
        //改变数为他每个数位的平方
           int result=0;
           while(n>0){
        //记住这里是想加
               result+=(n%10)*(n%10);
               n/=10;
           }
        //n变为result
            n=result;
        }
        //如果结果为1,就返回true,结果不为1,就返回false
        return n==1;
            
        }
    
}

题目四:1. 两数之和

做题思路

本题采用HashMap的解法思路,本质还是哈希表,重复元素这类知识

我们遍历整个数组,每次遍历到这个元素,就判断距离目标值还需要哪个值,如果这个值正好在map中,就返回这个值的下标和当前元素的下标

如果没有找到,就存储该元素的值为key(方便别人寻找),索引为value(找到的时候返回值要用到),记得这个值一定要存储为key,这样才能寻找得到,没有找到就记得把自身存进map

(为什么用map,我们既要存储值又要存储索引,同时我们还可以找到之前遍历过的元素的值,且题目中说数组中同一个元素在答案里不能重复出现,也就是值可以作为map的key,用指针去寻找太麻烦)

(找之前遍历过的元素,重复元素去重,就考虑哈希表法:hash数组,hashset,hashmap三种方法供选择)

具体代码
class Solution {
    public int[] twoSum(int[] nums, int target) {
        //思路:用hashmap解决,map用来存放我们遍历过的元素
        //初始化一个Map
        Map<Integer,Integer> map1=new HashMap<>();
        //遍历数组,每次存入数值
        for(int i=0;i<nums.length;i++){
            //达到目标值需要的值
            int result=target-nums[i];
            //如果在集合中,就将结果存入map集合中,然后返回
            if(map1.containsKey(result)){
            //返回顺序无所谓,我就随便返回了
                return new int[]{map1.get(result),i};
            }
            map1.put(nums[i],i);
        }
        return new int[]{};
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值