LeetCode 349:两个数组的交集

161 阅读2分钟

 LeetCode 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

计算两个数组的交集,直观的方法是遍历数组 nums1,对于其中的每个元素,遍历数组 nums2 判断该元素是否在数组 nums2 中,如果存在,则将该元素添加到返回值。 实现代码如下:

const set_intersection = (set1, set2) => {
    if (set1.size > set2.size) {
        return set_intersection(set2, set1);
    }
    const intersection = new Set();
    for (const num of set1) {
        // 判断该元素是否在set2 中
        if (set2.has(num)) {
            intersection.add(num);
        }
    }
    // 转换为数组
    return [...intersection];
}

var intersection = function(nums1, nums2) {
    const set1 = new Set(nums1);
    const set2 = new Set(nums2);
    return set_intersection(set1, set2);
}; 

时间复杂度:O(m+n); 其中 m 和 n 分别是两个数组的长度。使用两个集合分别存储两个数组中的元素需要 O(m+n) 的时间 空间复杂度:O(m+n); 其中 m 和 n 分别是两个数组的长度

思路三: 排序 + 双指针

  1. 两数组先进行排序: 利用sort方法;
  2. 创建intersection变量用于存放交集
  3. 两指针分别指向两数组的头部, 每次比较两个指针指向的两个数组中的数字
    • 不相等,则指向较小数组指针右移;
    • 相等,如果intersection数组为空或者值不等于intersection数组最后一个元素值,则push进结果,同时两指针都右移;
    • 当至少有一个指针超出数组范围时,遍历终止;

实现代码如下:

var intersection = function(nums1, nums2) {
    // 先进行排序
    nums1.sort((x, y) => x - y);
    nums2.sort((x, y) => x - y);
    const length1 = nums1.length, length2 = nums2.length;
    let index1 = 0, index2 = 0;
    const intersection = [];
    while (index1 < length1 && index2 < length2) {
        const num1 = nums1[index1], num2 = nums2[index2];
        if (num1 === num2) {
            // 保证加入元素的唯一性
            if (!intersection.length || num1 !== intersection[intersection.length - 1]) {
                intersection.push(num1);
            }
            index1++;
            index2++;
        } else if (num1 < num2) {
            index1++;
        } else {
            index2++;
        }
    }
    return intersection;
}; 

时间复杂度:O(mlogm+nlogn),其中 m 和 n 分别是两个数组的长度; 空间复杂度:O(mlogm+nlogn),其中 m 和 n 分别是两个数组的长度;

思路三:利用Set去重 + filter过滤

/**
 * @param {number[]} nums1
 * @param {number[]} nums2
 * @return {number[]}
 */
var intersection = function(nums1, nums2) {
  return [...new Set(nums1.filter((num) => nums2.includes(num)))]
};

参考资料

两个数组的交集- 力扣(LeetCode)