JavaScript算法每日一题两个数组的交集II

每日一题:每天一个新挑战;
循序渐进:从易到难,扎实掌握;
系统分类:按数据结构分类,有助于构建知识框架;
丰富题量:100 道精选题,覆盖简单/中等/困难难度。

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

示例 1:

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

示例 2:

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

提示:

  • 1 <= nums1.length, nums2.length <= 1000
  • 0 <= nums1[i], nums2[i] <= 1000

代码卡片

JavaScript算法每日一题两个数组的交集II

分析/求解

本题要求找到两个数组的交集,并且交集中的元素应根据其在两个数组中出现的最小次数来返回。输出结果可以是无序的。

方法一:哈希表

  1. 使用两个哈希表分别记录 nums1nums2 中每个元素的出现次数。
  2. 遍历其中一个哈希表,将每个元素在两个哈希表中的最小出现次数加入结果数组。
  • 时间复杂度: O(m + n),其中 m 和 n 分别是 nums1nums2 的长度。
  • 空间复杂度: O(min(m, n)),用于存储较小数组的频率表。
// 使用两个 哈希表 完成
var intersect = function (nums1, nums2) {
    const map1 = new Map();
    const map2 = new Map();
    const result = [];

    // 记录 nums1 的元素频率
    for (let num of nums1) {
        map1.set(num, (map1.get(num) || 0) + 1);
    }

    // 记录 nums2 的元素频率
    for (let num of nums2) {
        map2.set(num, (map2.get(num) || 0) + 1);
    }

    // 找到交集
    for (let [num, count] of map1) {
        if (map2.has(num)) {
            const minCount = Math.min(count, map2.get(num));
            for (let i = 0; i < minCount; i++) {
                result.push(num);
            }
        }
    }

    return result;
}

//  使用一个 哈希表 完成
var intersect = function (nums1, nums2) {
    const map = new Map();
    const result = [];

    // 记录 nums1 的元素频率
    for (let num of nums1) {
        map.set(num, (map.get(num) || 0) + 1);
    }

    // 找到 nums2 中的交集元素
    for (let num of nums2) {
        if (map.get(num) > 0) {
            result.push(num);
            map.set(num, map.get(num) - 1);
        }
    }

    return result;
}

方法二:排序 + 双指针

  1. 先将 nums1nums2 排序。
  2. 使用两个指针分别遍历两个数组,寻找相同的元素并加入结果数组。
  3. 如果元素相等,移动两个指针;如果 nums1[i] 小于 nums2[j],移动指针 i;否则移动指针 j。
  • 时间复杂度: O(m log m + n log n),因为需要对两个数组进行排序。
  • 空间复杂度: O(1),只使用了常数级别的额外空间。
var intersect = function (nums1, nums2) {
    nums1.sort((a, b) => a - b);
    nums2.sort((a, b) => a - b);
    let i = 0, j = 0;
    const result = [];

    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;
}

总结

  • 哈希表方法适合一般情况,尤其是未排序的数组。
  • 排序加双指针的方法适用于数组已排序的情况,并且在大数组情况下更优。

发布者:股市刺客,转载请注明出处:https://www.95sca.cn/archives/288999
站内所有文章皆来自网络转载或读者投稿,请勿用于商业用途。如有侵权、不妥之处,请联系站长并出示版权证明以便删除。敬请谅解!

(0)
股市刺客的头像股市刺客
上一篇 4小时前
下一篇 4小时前

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注