350. 两个数组的交集 II

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

方法一:哈希表

/**
 * @param {number[]} nums1
 * @param {number[]} nums2
 * @return {number[]}
 */
var intersect = function(nums1, nums2) {
  let m1 = nums1.length;
  let m2 = nums2.length;
  let map = new Map();
  let res = [];
  if(m1 > m2) return intersect(nums2, nums1)
  for(let i = 0;i < m1; i++){
    map.set(nums1[i], (map.get(nums1[i])||0 ) + 1);
  }
  for(let num of nums2){
    let count = map.get(num)||0;
    if(count > 0){
      res.push(num);
      map.set(num, count-1);
    }
  }
  return res;
};
from typing import collections, List


# class Solution:
#     def intersect(self, nums1: List[int], nums2: List[int]) -> List[int]:

class Solution:
  def intersect(self, nums1: List[int], nums2: List[int]) -> List[int]:
    if len(nums1) > len(nums2):
      return self.intersect(nums2, nums1)
      
    m = collections.Counter()
    for num in nums1:
      m[num] += 1
    
    ret = list()
    for num in nums2:
      count = m.get(num)
      if count and count > 0:
        ret.append((num))
        m[num] -= 1
        if m[num] == 0:
          m.pop(num)
    
    return ret


if __name__ == '__main__':
  so = Solution()

  nums1, nums2 = [1,2,2,1], [2,2]
  print(nums1, nums2, so.intersect(nums1, nums2) )
  nums1, nums2 = [4,9,5], [9,4,9,8,4]
  print(nums1, nums2, so.intersect(nums1, nums2) )

 

方法二:排序 + 双指针

/**
 * @param {number[]} nums1
 * @param {number[]} nums2
 * @return {number[]}
 */
var intersect = function(nums1, nums2) {
  let m1 = nums1.length;
  let m2 = nums2.length;
  let res = [];
  
  nums1.sort((a, b)=>a-b);
  nums2.sort((a, b)=>a-b);
  let i = 0, j = 0;
  while(i < m1 && j < m2){
    if(nums1[i] === nums2[j]){
      res.push(nums1[i]);
      i += 1;
      j += 1;
    }else if(nums1[i] > nums2[j]){
      j += 1;
    }else{
      i += 1;
    }
  }
  return res;
};
from typing import List


class Solution:
    def intersect(self, nums1: List[int], nums2: List[int]) -> List[int]:
      nums1.sort()
      nums2.sort()
      p1, p2 = 0, 0
      retList = list()
      m1, m2 = len(nums1), len(nums2)
      while p1<m1 and p2<m2:
        if nums1[p1] < nums2[p2]:
          p1 += 1
        elif nums1[p1] > nums2[p2]:
          p2 += 1
        else:
          retList.append(nums1[p1])
          p1 += 1
          p2 += 1
      return retList

if __name__ == '__main__':
  so = Solution()

  nums1, nums2 = [1,2,2,1], [2,2]
  print(nums1, nums2, so.intersect(nums1, nums2) )
  nums1, nums2 = [4,9,5], [9,4,9,8,4]
  print(nums1, nums2, so.intersect(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]

 

说明:

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

进阶:

  • 如果给定的数组已经排好序呢?你将如何优化你的算法?
  • 如果 nums1 的大小比 nums2 小很多,哪种方法更优?
  • 如果 nums2 的元素存储在磁盘上,内存是有限的,并且你不能一次加载所有的元素到内存中,你该怎么办?
posted @ 2021-07-07 10:13  尖子  阅读(48)  评论(0编辑  收藏  举报