一天一大 leet(两个数组的交集 II)难度:简单-Day20200713

时间:2022-07-25
本文章向大家介绍一天一大 leet(两个数组的交集 II)难度:简单-Day20200713,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

题目:

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

示例

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

说明

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

进阶

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

抛砖引玉

  • 遍历其中一个数组 nums1 在另外一个数组 nums2 红检查是否存在该元素
    • 存在放入结果中,并在 nums2 中清除
    • 不存在则不作任何操作
/**
 * @param {number[]} nums1
 * @param {number[]} nums2
 * @return {number[]}
 */
var intersect = function (nums1, nums2) {
  let _result = []
  for (let i = 0; i < nums1.length; i++) {
    let index = nums2.indexOf(nums1[i])
    if (index > -1) {
      _result.push(nums1[i])
      nums2.splice(index, 1)
    }
  }
  return _result
}

官方答案:

  1. 哈希表
  • 利用 map 记录较短数组中每个数组出现的次数
  • 遍历较长数组到 map 中检查这个数组是否在 map 中且遇到次数不为 0
    • 次数大于 0,存放到结果数组中,且更新 map 中统计的个数
    • 小于等 0,则这个数字在较短数组没出现
/**
 * @param {number[]} nums1
 * @param {number[]} nums2
 * @return {number[]}
 */
var intersect = function (nums1, nums2) {
  if (nums1.length > nums2.length) {
    return intersect(nums2, nums1)
  }
  let map = new Map()
  for (let i = 0; i < nums1.length; i++) {
    let count = (map.get(nums1[i]) || 0) + 1
    map.set(nums1[i], count)
  }
  let _result = []
  for (let i = 0; i < nums2.length; i++) {
    let count = map.get(nums2[i]) || 0
    if (count > 0) {
      _result.push(nums2[i])
      map.set(nums2[i], count - 1)
    }
  }
  return _result
}
  1. 排序
  • 先对两个数组排序优化循环
  • 从零遍历两个数组,比较两个数组不用指针下的元素大小
    • 其中一个数组当前指针下数字小,则后移指针去查询到比另外一个数组指针下等于小于其的数
    • 两数相同记录到结果中切两个指针同时后移
/**
 * @param {number[]} nums1
 * @param {number[]} nums2
 * @return {number[]}
 */
var intersect = function (nums1, nums2) {
  nums1.sort((a, b) => a - b)
  nums2.sort((a, b) => a - b)
  let len1 = nums1.length,
    len2 = nums2.length,
    _result = [],
    i = 0,
    j = 0,
    index = 0
  while (i < len1 && j < len2) {
    if (nums1[i] < nums2[j]) {
      i++
    } else if (nums1[i] > nums2[j]) {
      j++
    } else {
      _result[index] = nums1[i]
      i++
      j++
      index++
    }
  }
  return _result
}