LeetCode——两个数组的交集 II

129 阅读2分钟

「这是我参与2022首次更文挑战的第15天,活动详情查看:2022首次更文挑战」。

前言

大家好,我是程序猿小白 GW_gw,很高兴能和大家一起学习进步。

以下内容部分来自于网络,如有侵权,请联系我删除,本文仅用于学习交流,不用作任何商业用途。

摘要

本文主要介绍LeetCode两个数组的交集II的一些解法和思路。

【题目】

给你两个整数数组 nums1 和 nums2 ,请你以数组形式返回两数组的交集。返回结果中每个元素出现的次数,应与元素在两个数组中都出现的次数一致(如果出现次数不一致,则考虑取较小值)。可以不考虑输出结果的顺序。

  示例 1:

输入:nums1 = [1,2,2,1], nums2 = [2,2]

输出:[2,2]

题目链接:leetcode-cn.com/leetbook/re…

【解法一】

【思路】

暴力循环:逐个判断元素是否存在于另一个数组中,如果存在则把该元素放到返回的数组中,并且把该元素赋值为负数(相反数,题目中的测试用例都是大于0的),以免影响后面的判断。

【代码】

public static int[] intersect(int[] nums1, int[] nums2) {
    /*
    解法1:暴力循环
     */
    List<Integer> res = new ArrayList();
    for (int i = 0; i < nums1.length; i++) {
        for (int j = 0; j < nums2.length; j++) {
            if(nums1[i]==nums2[j]){
                res.add(nums1[i]);
                nums2[j] = -nums2[j];
                break;
            }
        }
    }
    int[] arr = new int[res.size()];
    int index=0;
    for (int i = 0; i < res.size(); i++) {
        arr[index++] = res.get(i);
    }
    return arr;
}

【解法二】

【思路】

排序加双指针:

首先对两个数组进行排序。设置两个指针分别指向数组的首部。循环依次比较。

  • 如果两个指针指向的值相同,则把该元素放入到返回的数组中。
  • 如果不同,则把两个指针指向的更小的元素往后挪一位。

【代码】

public static int[] intersect(int[] nums1, int[] nums2){
    /*
    解法2:排序+双指针
     */
     //先对两个数组分别进行排序
    Arrays.sort(nums1);
    Arrays.sort(nums2);
    int i=0;
    int j=0;
    List<Integer> res = new ArrayList();
    while(i<nums1.length && j<nums2.length){
        if(nums1[i]==nums2[j]){
        //相等就加入到集合中
            res.add(nums1[i]);
            i++;
            j++;
        }
        //不相等,值小的指针往后移
        else if(nums1[i]>nums2[j]){
            j++;
        }else{
            i++;
        }
    }
    int[] arr = new int[res.size()];
    int index=0;
    for (int p = 0; p < res.size(); p++) {
        arr[index++] = res.get(p);
    }
    return arr;
}

【解法三】

【思路】

使用map集合:

找出两个数组中长度最小的以减少时间复杂度。

  • 把数组1的元素逐个加入到map中,key为元素值,value初始值为1,如果后面还有则把value++,即value表示数组中重复元素的个数
  • 遍历数组2,如果map中包含该元素,并且value值大于0,就把value--(这里才能够保证是按照最小的相同数量放入最后返回的数组中),然后把该元素放入到数组中。

【代码】

public static int[] intersect(int[] nums1, int[] nums2){
    /*
    解法3:使用map
     */
    if(nums1.length>nums2.length){
        return intersect(nums2,nums1);
    }
    int[] res = new int[nums1.length];
    int index=0;
    Map<Integer,Integer> map = new HashMap<>(1068);
    //800/0.75+1 = 1068 初始化map的初始容量计算
    for (int i = 0; i < nums1.length; i++) {
    //getOrDeafult方法如果包含该键就返回其value值,如果不包含返回默认值
        map.put(nums1[i],map.getOrDefault(nums1[i],0)+1);
    }
    for (int i = 0; i < nums2.length; i++) {
        if(map.getOrDefault(nums2[i],0)>0){
            res[index++] = nums2[i];
            map.put(nums2[i], map.get(nums2[i])-1);
        }
    }
    return Arrays.copyOfRange(res,0,index);
}

小结

以上就是该题的三种解法,其中第三种方法利用map集合的特性,值得我们学习,希望以上内容能对读者有所帮助,如有不正之处,欢迎留言指正。