码迷,mamicode.com
首页 > 编程语言 > 详细

两个数组的交集

时间:2020-11-18 12:29:55      阅读:6      评论:0      收藏:0      [点我收藏+]

标签:出现   star   java   数组的交集   时间复杂度   示例   hash表   +=   磁盘   

1.问题描述

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

示例 1:

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

示例 2:

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

说明:

  • 输出结果中每个元素出现的次数,应与元素在两个数组中出现次数的最小值一致。
  • 我们可以不考虑输出结果的顺序。

****进阶

  • 如果给定的数组已经排好序呢?你将如何优化你的算法?
  • 如果 nums1 的大小比 nums2 小很多,哪种方法更优?
  • 如果 nums2 的元素存储在磁盘上,内存是有限的,并且你不能一次加载所有的元素到内存中,你该怎么办?

2.求解

哈希表

  • 比较两个数组的长度,遍历较大的数组,将其存入元素作为键,出现次数作为值,存入hash表中
  • 遍历另一个较小的数组,若它的元素在哈希表中出现,即把其存入新的数组中,并且将出现次数减一,重新存入哈希表中

代码如下

/*
* 执行用时:4 ms, 在所有 Java 提交中击败了53.75% 的用户
* 内存消耗:38.9 MB, 在所有 Java 提交中击败了51.97% 的用户
* */
public int[] intersect(int[] nums1, int[] nums2) {
    if(nums2.length > nums1.length){
        return intersect(nums2,nums1);
    }
    Map<Integer, Integer> map = new HashMap<>();
    for(int num : nums1){
        map.merge(num, 1, (oldX, newX) -> oldX += 1);
    }
    int[] res = new int[nums1.length];
    int index = 0;
    for(int num : nums2){
        int count = map.getOrDefault(num, 0);
        if(count > 0){
            res[index] = num;
            index ++;
            count --;
        }
        map.put(num, count);
    }
    return Arrays.copyOfRange(res, 0, index);
}
  • 时间复杂度:O(n),n为两数组大小之和
  • 空间复杂度:O(n),n为较小数组元素个数

ps:对int[]数组的复制操作

  • System.arraycopy(arr, copied, start, end);

  • Arrays.copyOfRange(intersection, 0, index);

    区别:Arrays.copyOf()不仅仅只是拷贝数组中的元素,在拷贝元素时,会创建一个新的数组对象。而System.arrayCopy只拷贝已经存在数组元素。

    ? Array.copyOf()底层是调用的System.arrayCopy(new了一个数组对象,复制后返回)

排序 + 双指针

代码如下

    /*
     *执行用时:1 ms, 在所有 Java 提交中击败了100.00% 的用户
     *内存消耗:38.8 MB, 在所有 Java 提交中击败了75.93% 的用户
     */
	public int[] intersect(int[] nums1, int[] nums2) {
        Arrays.sort(nums1);
        Arrays.sort(nums2);
        int m = nums1.length;
        int n = nums2.length;
        int[] res = new int[m + n];
        int length = 0;
        int i = 0, j = 0;
        while(i < m && j < n){
            if(nums1[i] == nums2[j]){
                res[length] = nums1[i];
                length++;
                i++;
                j++;
            }else if(nums1[i] < nums2[j]){
                i++;
            }else{
                j++;
            }
        }
        return Arrays.copyOfRange(res, 0, length);
    }
  • 时间复杂度:O(mlog?m+nlog?n),排序的时间复杂度是O(mlog?m+nlog?n),遍历的时间复杂度是O(m + n),所以总的时间复杂度是O(mlogm + nlogn)
  • 空间复杂度:O(m +n)

ps:这里新建数组可以改成如下。

? int[] res = new int[Math.min(m,n)],这样空间复杂度就变成了O(min(m,n))

两个数组的交集

标签:出现   star   java   数组的交集   时间复杂度   示例   hash表   +=   磁盘   

原文地址:https://www.cnblogs.com/g9420/p/13964212.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!