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


java哈希结构总结:

https://www.runoob.com/java/java-collections.html
https://blog.csdn.net/qq_34332616/article/details/114692538

哈希表理论基础

https://programmercarl.com/%E5%93%88%E5%B8%8C%E8%A1%A8%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html#%E5%93%88%E5%B8%8C%E8%A1%A8

242. 有效的字母异位词

教程视频:https://www.bilibili.com/video/BV1YG411p7BA/?spm_id_from=333.788&vd_source=ddffd51aa532d23e6feac69924e20891
在这里插入图片描述

解法一:数组统计

    public boolean isAnagram(String s, String t) {
        //长度不相等必定不是
        if(s.length()!=t.length()){
            return false;
        }
        
        int[] num = new int[26];
        char[] charArr1 = s.toCharArray();
        for(int i=0;i<s.length();i++){
            num[charArr1[i]-'a'] +=1;
        }
        // System.out.println(num);
        char[] charArr2 = t.toCharArray();
        for(int i=0;i<t.length();i++){
            num[charArr2[i]-'a'] -=1;
        }

        for(int i=0;i<num.length;i++){
            if(num[i]!=0){
                return false;
            }
        }
        return true;
    }

349. 两个数组的交集

教程视频:https://www.bilibili.com/video/BV1ba411S7wu/?spm_id_from=333.788&vd_source=ddffd51aa532d23e6feac69924e20891
在这里插入图片描述

解法一:HashSet

使用HashSet时记得指定泛型, 否则得到的Set内元素是Object, 后续转为数组会出错.

    public int[] intersection(int[] nums1, int[] nums2) {
        HashSet<Integer> records = new HashSet<>();
        HashSet<Integer> result = new HashSet<>();
        // 去重复并存入records
        for(int i=0;i<nums1.length;i++){
            records.add(nums1[i]);
        }
        //查找重复值存入result集合
        for(int i=0;i<nums2.length;i++){
            if(records.contains(nums2[i])){
                result.add(nums2[i]);
            }
        }
        //方法1:将结果集合转为数组
        //return result.stream().mapToInt(x -> x).toArray();

        //方法2:另外申请一个数组存放result中的元素,最后返回数组
        int[] arr = new int[result.size()];
        int j = 0;
        for(int i : result){
            arr[j++] = i;
        }
        return arr;
    }

解法二:数组记录

力扣给的范围是: 0 <= nums1[i], nums2[i] <= 1000
因此可以使用数组记录字符位置

    public int[] intersection(int[] nums1, int[] nums2) {
        int[] records = new int[1001];
        for(int num: nums1){
            records[num] = 1;
        }
        HashSet<Integer> res = new HashSet<>();
        for(int num : nums2){
            if(records[num]==1){
                res.add(num);
            }
        }
        int[] result = new int[res.size()];
        int j = 0;
        for(int i : res){
            result[j++] = i;
        }
        return result;

    }

202. 快乐数

教程:https://programmercarl.com/0202.%E5%BF%AB%E4%B9%90%E6%95%B0.html
在这里插入图片描述

解法一:优

    public boolean isHappy(int n) {
        HashSet<Integer> record = new HashSet<>();
        while(!record.contains(n)){
            record.add(n);
            n =getNextNumber(n);
            if(n==1){return true;}
        }
        return false;
    }

    //计算返回n每个位置上的数字的平方和
    private int getNextNumber(int n) {
        int sum = 0;
        while (n > 0) {
            int temp = n % 10;
            sum += (n % 10) * (n % 10);
            n = n / 10;
        }
        return sum;
    }

解法二:没单独写出函数

    public boolean isHappy(int n) {
        HashSet<Integer> records = new HashSet<>();
        records.add(n);
        int sum = 0 ;
        while(!records.contains(sum)){
            // 将上一次循环数得到的存入集合中
            records.add(sum);
            //得到下一个数存到sum
            sum=0;
            while(n!=0){
                sum+=(n%10)*(n%10);
                n = n/10;
            }
            //如果得到1,满足要求返回true
            if(sum==1){
                return true;
            }
            //否则将n改为下个数
            n=sum;
        }
        return false;
    }

1. 两数之和

教程视频:https://www.bilibili.com/video/BV1aT41177mK/?spm_id_from=333.788&vd_source=ddffd51aa532d23e6feac69924e20891
在这里插入图片描述
进阶:你可以想出一个时间复杂度小于 O(n2) 的算法吗?

解法一:HashMap记录已经遍历过的数值和索引

    public int[] twoSum(int[] nums, int target) {
        HashMap<Integer, Integer>  record = new HashMap<>();
        for(int i=0;i<nums.length;i++){
            if(record.containsKey(target-nums[i])){
                return new int[]{record.get(target-nums[i]),i};
            }
            record.put(nums[i],i);
        }
        return new int[2];
    }

解法二:暴力破解,双重for循环

时间复杂度高,暂不实现.


总结

1.当需要快速寻找之前遍历过的内容,使用哈希结构.
2.数组适用于有限内容的查找; HashSet适用于去重复查找; HashMap适合带键值对的查找.
3.使用HashSet和HashMap时记得指定泛型, 否则得到的集合内元素是Object.

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值