两个数组的交集【349】

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

示例 1:

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

示例 2:

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

一.双集合

思路:

将两个数组分别放入两个set集合中,比较一个集合是否包含另一个集合的字段,如果包含就放入集合中
class Solution {
    public int[] intersection(int[] nums1, int[] nums2) {

        List<Integer> list = new ArrayList();

        Set<Integer> num1Set = new HashSet();
        Set<Integer> num2Set = new HashSet();

        for(int i = 0; i < nums1.length; i++){
            num1Set.add(nums1[i]);
        }

        for(int i = 0; i < nums2.length; i++){
            num2Set.add(nums2[i]);
        }
         for(int key: num1Set){
            if(num2Set.contains(key)){
                list.add(key);
            }
        }

        int num3[] = list.stream().mapToInt(Integer::valueOf).toArray();

        return  num3;
        
    }
}

//大佬的写法:
public int[] intersection(int[] nums1, int[] nums2) {
    Set<Integer> set = Arrays.stream(nums1).boxed().collect(Collectors.toSet());
    return Arrays.stream(nums2).distinct().filter(set::contains).toArray();
}

复杂度分析

  • 时间复杂度:O(m+n),其中 m 和 n 分别是两个数组的长度。使用两个集合分别存储两个数组中的元素需要 O(m+n) 的时间,遍历较小的集合并判断元素是否在另一个集合中需要O(min(m,n)) 的时间,因此总时间复杂度是 O(m+n)。
  • 空间复杂度:O(m+n),其中 m 和 n 分别是两个数组的长度。空间复杂度主要取决于两个集合。

二.排序 + 双指针

思路:

首先对两个数组进行排序,然后使用两个指针遍历两个数组。可以预见的是加入答案的数组的元素一定是递增的,为了保证加入元素的唯一性,我们需要额外记录变量 pre表示上一次加入答案数组的元素。
初始时,两个指针分别指向两个数组的头部。每次比较两个指针指向的两个数组中的数字,如果两个数字不相等,则将指向较小数字的指针右移一位,如果两个数字相等,且该数字不等于 pre ,
将该数字添加到答案并更新 pre 变量,同时将两个指针都右移一位。当至少有一个指针超出数组范围时,遍历结束。

代码:

class Solution {
    public int[] intersection(int[] nums1, int[] nums2) {
        Arrays.sort(nums1);
        Arrays.sort(nums2);
        int length1 = nums1.length, length2 = nums2.length;
        int[] intersection = new int[length1 + length2];
        int index = 0, index1 = 0, index2 = 0;
        while (index1 < length1 && index2 < length2) {
            int num1 = nums1[index1], num2 = nums2[index2];
            if (num1 == num2) {
                // 保证加入元素的唯一性
                if (index == 0 || num1 != intersection[index - 1]) {
                    intersection[index++] = num1;
                }
                index1++;
                index2++;
            } else if (num1 < num2) {
                index1++;
            } else {
                index2++;
            }
        }
        return Arrays.copyOfRange(intersection, 0, index);
    }
}

复杂度分析

  • 时间复杂度:O(mlogm+nlogn),其中 m 和 n 分别是两个数组的长度。对两个数组排序的时间复杂度分别是 O(mlogm) 和 O(nlogn),双指针寻找交集元素的时间复杂度是 O(m+n),因此总时间复杂度是 O(mlogm+nlogn)。

  • 空间复杂度:O(logm+logn),其中 m 和 n 分别是两个数组的长度。空间复杂度主要取决于排序使用的额外空间。

posted @ 2020-11-02 17:43  snail灬  阅读(96)  评论(0编辑  收藏  举报