力扣 349 两个数组的交集


题目链接

https://leetcode-cn.com/problems/intersection-of-two-arrays

源代码 github 地址

https://github.com/YIMEng-0/DataStructure

1、题目要求

给定两个数组,编写一个函数来计算它们的交集。

示例 1:
输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2]

示例 2:
输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出:[9,4]

说明:
输出结果中的每个元素一定是唯一的。
我们可以不考虑输出结果的顺序。

2、思路分析

输入两个 int 类型的数组,先将第一个数组中的所有元素放置在 set 类型的哈希表中(放置在 set1 中);(这个操作的目的是将数组 1 中的重复元素过滤)
然后遍历第二个数组,将第二个数组中和 set1 的元素做比较,如果 set1 中包含第二个数组的元素,那么保存在 resSet 中;(这个操作是找出来两个数组中的交集,也就是两个数组中都存在的元素)

3、执行代码 java

class Solution {
    public int[] intersection(int[] nums1, int[] nums2) {
        Set<Integer> set1 = new HashSet<>();
        Set<Integer> resSet = new HashSet<>();

        // 剔除第一个数组中重复的元素
        for(int i:nums1) {
            set1.add(i);
        }

        // 在经过了重复元素剔除之后的第一个数组,寻找set 中有没有和第二个数组重复的元素(重复了就说明是包含的),包含了那就说明这是两个数组中公共的元素,保存在结果数据集合中
        for(int i:nums2) {
            if(set1.contains(i)) {
                resSet.add(i);
            }
        }

        // 这里使用的是 size() 方法 知道 set 集合里面元素的多少
        int[] resArr = new int[resSet.size()];

        int index = 0;
        for(int i:resSet) {
            resArr[index] = i;
            index++;

            // 相当于 res[index++] = i;
            // 两种写法都是正确的,下面的容易理解一些
        }

        return resArr;
    }
}

下面的这种解答方式也是正确的,思路都是一样的:

class Solution {
    public int[] intersection(int[] nums1, int[] nums2) {
        Set<Integer> set1 = new HashSet<>();
        Set<Integer> resSet = new HashSet<>();

        // 对于数组中的元素,遍历,保存在 Set 集合容器中,保持一种没有重复,无序的状态
        for(int i = 0;i < nums1.length;i++) {
            set1.add(nums1[i]);
        }

        for(int i = 0;i < nums2.length;i++) {
            if(set1.contains(nums2[i])){
                resSet.add(nums2[i]);
            }
        }


        int[] resArr = new int[resSet.size()];
        int index = 0;

        // 一个已经知道的数组,赋值给一个空数组,使用加强 for 循环进行遍历
        // 中间需要使用 index 进行变量的控制
        for(int i : resSet) {
            resArr[index] = i;
            index++;
        }

        return resArr;
    }
}

4、问题反思

4.1、为什么使用 set 集合?

因为题目中的要求是唯一可以没有顺序,所以使用 set 集合是十分方便的;

4.2、Java 集合的继承关系图

在这里插入图片描述

4.3、HashSet 的部分知识点

HashSet实现Set接口,底层由HashMap来实现,为哈希表结构,新增元素相当于HashMap的key,value默认为一个固定的Object。HashSet可以理解为一个阉割版的HashMap;

当有元素插入的时候,会计算元素的hashCode值,将元素插入到哈希表对应的位置中来;

它继承于AbstractSet,实现了Set, Cloneable, Serializable接口。

  • (1)HashSet继承AbstractSet类,获得了Set接口大部分的实现,减少了实现此接口所需的工作,实际上是又继承了AbstractCollection类;

  • (2)HashSet实现了Set接口,获取Set接口的方法,可以自定义具体实现,也可以继承AbstractSet类中的实现;

  • (3)HashSet实现Cloneable,得到了clone()方法,可以实现克隆功能;

  • (4)HashSet实现Serializable,表示可以被序列化,通过序列化去传输,典型的应用就是hessian协议。

具有如下特点:

  • 不允许出现重复因素;
  • 允许插入Null值;
  • 元素无序(添加顺序和遍历顺序不一致);
  • 线程不安全,若2个线程同时操作HashSet,必须通过代码实现同步;

4.4 关于数组转换里面的 for 循环

        for(int i:resSet) {
            resArr[index] = i;
            index++;

           //循环体里面的两行代码相当于下面的一行代码 
           res[index++] = i;
            // 两种写法都是正确的,上面的容易理解一些
        }

5、小结

通过 Set 集合中的 HashSet 集合,可以使得保存在里面的元素不重复无序,这是解决本题目的重要思路;
对于 HashSet 的知识需要熟练掌握;

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值