leetcode(350. 两个数组的交集 II)

234 阅读1分钟

image.png

方法一:双指针进行比较

看到这道题,想起来在学校OJ上做过的一道关于链表的交集,本质上两道题解法也相同

思路:

  1. 首先将数组进行排序,再设置两个指针分别指向两个数组的头部
  2. 然后比较指针指向的数据是否相等,如果相等,则将该数据存入答案 res 数组中,最后将两个指针都向后移动一位
  3. 如果数据不相等,则将数据较小的指针向后移动,然后重复 2,3 步,直至有一个指针超出范围
var intersect = function (nums1, nums2) {
    nums1=nums1.sort((a,b)=>a-b)
    nums2=nums2.sort((a,b)=>a-b)
    let i=0,j=0
    let res=[]
    while(i<nums1.length&&j<nums2.length){
        if(nums1[i]==nums2[j]){
            res.push(nums1[i])
            i++
            j++
        }
        else if(nums1[i]<nums2[j]){
            i++
        }
        else if(nums1[i]>nums2[j]){
            j++
        }
    }
    return res
};

时间复杂度:官网说是 O(mlogm+nlogn) 我是有点疑问的,可能根据 sort 在不同引擎下执行机制不同吧

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

方法二:哈希表

思路:

  1. 给定指定一个数组创建存储每个数字在该数组中出现次数的哈希表
  2. 遍历第二个数组,如果哈希表中存在这个数字且次数不为0,那么添加到答案 res 数组中,并将哈希表中该数字出现次数减去一
let hashmap = {}
let res=[]
for (let i = 0; i < nums1.length; i++) {
     if (!hashmap.hasOwnProperty(nums1[i])) {
                hashmap[nums1[i]] = 1
     }
     else{
                hashmap[nums1[i]]++
     }
}
for(let i=0;i<nums2.length;i++){
     if(hashmap.hasOwnProperty(nums2[i]) && hashmap[nums2[i]]>0){
                res.push(nums2[i])
                hashmap[nums2[i]]--
     }
}    
return res

如果两个数组的长度差别很大,nums1 比 nums2 大的多,能怎么优化

实际上解决办法就是:对长度较小的数组创建哈希表,降低了空间复杂度

if(nums1.length>nums2.length) return  intersect(nums2,nums1)

时间复杂度:O(m+n)

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