LC350. 两个数组的交集 II(第12题)

177 阅读3分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

菜鸟就要从第12题继续

一、题目描述:

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

进阶:

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

来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/in… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

二、思路分析:

第一版:暴力求解,遍历num1与num2,判断是否存在相等的数,相等则在num2中删除响应数,同时注意判断两个是否已完成全部遍历。

哈希优化:分别遍历,遍历第一个时在map中填入数及对应次数,然后再遍历第二个数组,如果找到对应元素,则添加这个元素到返回数组里。如果值大于1,HashMap中的值减1。如果value值等于1,则删除该元素。

  • 这部分代码在写的时候首先要注意长短的判断和交换(这里直接调用原函数,修改数据传入顺序,我竟然都没想到) 另一方面在这里区分下const let var js的三种声明方式:
  1. const定义的变量不可以修改,而且必须初始化,块级作用域,如果声明的是复合类型数据,可以修改其属性;
  2. var定义的变量可以修改,如果不初始化会输出undefined,不会报错。var声明变量存在变量提升,let和const不存在变量提升;
  3. let是块级作用域。

排序双指针:先对两个数组从小到大排序,然后利用双指针的思路进行求解。

三、AC 代码:

1、第一版

/**
 * @param {number[]} nums1
 * @param {number[]} nums2
 * @return {number[]}
 */
var intersect = function(nums1, nums2) {
    let l1=nums1.length
    let l2=nums2.length
    let index
    let result = new Array()
    let i=0
    while(i<l1&&l2>=0){
        index = nums2.indexOf(nums1[i])
        if(index!=-1){
            result.push(nums1[i])
            nums2.splice(index,1)
            l2-=1
        }
        i++
    }
    return result
};

2、哈希优化

/**
 * @param {number[]} nums1
 * @param {number[]} nums2
 * @return {number[]}
 */
var intersect = function(nums1, nums2) {
    if (nums1.length > nums2.length) {
            return intersect(nums2, nums1)
    }
    const hashmap = new Map()
    for (let num of nums1) {
        let count = hashmap.get(num) || 0
        hashmap.set(num, count+1)
    }
    let res = [], index = 0
    for (let num of nums2) {
        let count = hashmap.get(num) || 0
        if (count > 0) {
            res[index++] = num
            count--
            if (count > 0) {
                hashmap.set(num, count)
            } else {
                hashmap.delete(num)
            }
        }
    }
    return res
};

3、排序双指针

/**
 * @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 res = []
    let key1 = 0, key2 = 0, index = 0
    while(key1 < nums1.length && key2 < nums2.length){
        if(nums1[key1] < nums2[key2]) key1++
        else if(nums1[key1] > nums2[key2]) key2++
        else{
            res[index++] = nums1[key1]
            key1++
            key2++
        }
    }
    return res
};