LeetCode -- 350. 两个数组的交集 II(简单)

15 阅读2分钟

350. 两个数组的交集 II

题目描述

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

输入/输出示例

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

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

常规解法

关键思路 - Map字符存储

  • 用map存储数组每个元素的出现次数。

JS代码实现

/**
 * @param {number[]} nums1
 * @param {number[]} nums2
 * @return {number[]}
 */
const intersect = (nums1, nums2) => {
    const result = [];
    const map = new Map();
    // 将nums1中的元素存入map中,key为元素,value为出现次数
    for (const num of nums1) {
        map.set(num, (map.get(num) || 0) + 1);
    }
    // 遍历nums2,如果map中有该元素,则将其加入result中,并将map中该元素的次数减1
    for (const num of nums2) {
        if(map.has(num) && map.get(num)){
            result.push(num);
            map.set(num, map.get(num) - 1);
        }
    }
    return result;
};

复杂度分析

  • 时间复杂度:O(m + n)
  • 空间复杂度:O(min(m, n))

优化解法

关键思路 - 排序+双指针

  • 先对两个数组进行排序,然后用双指针同时遍历两个数组。
  • 该方法适用于已经排好序的数组。

JS代码实现

/**
 * @param {number[]} nums1
 * @param {number[]} nums2
 * @return {number[]}
 */
const intersect = (nums1, nums2) => {
    const result = [];
    nums1.sort((a, b) => a - b);
    nums2.sort((a, b) => a - b);
    let i = 0;  // nums1的指针
    let j = 0;  // nums2的指针
    while (i < nums1.length && j < nums2.length) {
        if (nums1[i] === nums2[j]) {
            result.push(nums1[i]);
            i++;
            j++;
        } else if (nums1[i] < nums2[j]) {
            i++;
        } else {
            j++;
        }
    }
    return result;
};

复杂度分析

  • 时间复杂度:O(m log m + n log n),主要是排序的开销
  • 空间复杂度:O(log m + log n) 或 O(1),取决于排序算法的实现

结语

本文主要介绍了LeetCode第350题两个数组的交集II的两种解法,你还知道这题的其他解法吗?欢迎在评论区留言分享!