首页 > 编程语言 > 详细

leetcode350:两个数组的交集Ⅱ

时间:2020-08-12 20:09:02      阅读:72      评论:0      收藏:0      [点我收藏+]

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

示例1:

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

示例2:

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

说明:

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

==》map映射

=================================Python===============================

class Solution:
    def intersect(self, nums1: List[int], nums2: List[int]) -> List[int]:
        dic1 = {}
        dic2 = {}
        for val in nums1:
            if val in dic1:
                dic1[val] += 1
            else:
                dic1[val] = 1
        for val2 in nums2:
            if val2 in dic2:
                dic2[val2] += 1
            else:
                dic2[val2] = 1
        res = []
        for key, value in dic1.items():
            if key in dic2:
                for _ in range(min(dic2[key], value)):
                    res.append(key)
        return res
----------------------------优化------------------------------
class Solution:
    def intersect(self, nums1: List[int], nums2: List[int]) -> List[int]:
        dic = {}
        for val in nums1:
            if val in dic:
                dic[val] += 1
            else:
                dic[val] = 1
        k = 0
        for value in nums2:
            if dic.get(value, 0) > 0:
                dic[value] -= 1
                nums2[k] = value
                k += 1
        return nums2[:k]

========================================Go======================================

func intersect(nums1 []int, nums2 []int) []int {
    m0 := map[int]int{}
    for _, v := range nums1 {
        m0[v] += 1
    }
    k := 0
    for _, v := range nums2 {
        if m0[v] > 0 {
            m0[v] -= 1
            nums2[k] = v
            k++
        }
    }
    return nums2[0:k]
}

=====================================Java=================================

class Solution {
    public int[] intersect(int[] nums1, int[] nums2) {
        HashMap<Integer, Integer> map1 = new HashMap<>();
        for (int num: nums1){
            int count = map1.getOrDefault(num, 0) + 1;
            map1.put(num, count);
        }

        int[] res = new int[nums1.length]; 
        int index = 0;
        for (int num: nums2){
            int count = map1.getOrDefault(num, 0);
            if (count > 0) {
                count--;
                res[index++] = num;
                if (count > 0) {
                    map1.put(num, count);
                } else {
                    map1.remove(num);
                }
            }
        }

        return Arrays.copyOfRange(res, 0, index);
    }
}

 

进阶:

如果给定的数组已经排好序呢?你将如何优化你的算法?
如果 nums1 的大小比 nums2 小很多,哪种方法更优?

技术分享图片

 

 


如果 nums2 的元素存储在磁盘上,磁盘内存是有限的,并且你不能一次加载所有的元素到内存中,你该怎么办?

对应进阶问题三,如果内存十分小,不足以将数组全部载入内存,那么必然也不能使用哈希这类费空间的算法,只能选用空间复杂度最小的算法。

一般说排序算法都是针对于内部排序,一旦涉及到跟磁盘打交道(外部排序),则需要特殊的考虑。归并排序是天然适合外部排序的算法,可以将分割后的子数组写到单个文件中,归并时将小文件合并为更大的文件。当两个数组均排序完成生成两个大文件后,即可使用双指针遍历两个文件,如此可以使空间复杂度最低。

双指针

===============Python=============

class Solution:
    def intersect(self, nums1: List[int], nums2: List[int]) -> List[int]:
        nums1.sort()
        nums2.sort()
        i = j = 0
        res = []
        while i < len(nums1) and j < len(nums2):
            if nums1[i] == nums2[j]:
                res.append(nums1[i])
                i += 1
                j += 1
            elif nums1[i] < nums2[j]:
                i += 1
            else:
                j += 1
        return res

============Go==========

func intersect(nums1 []int, nums2 []int) []int {
    i, j, k := 0, 0, 0
    sort.Ints(nums1)
    sort.Ints(nums2)
    for i < len(nums1) && j < len(nums2) {
        if nums1[i] > nums2[j] {
            j++
        } else if nums1[i] < nums2[j] {
            i++
        } else {
            nums1[k] = nums1[i]
            i++
            j++
            k++ 
        }
    }
    return nums1[:k]
}

======================Java====================

class Solution {
    public int[] intersect(int[] nums1, int[] nums2) {
       Arrays.sort(nums1);
       Arrays.sort(nums2);
       int l1 = nums1.length;
       int l2 = nums2.length;
       int i = 0;
       int j = 0;
       int index = 0;
       while (i < l1 && j < l2) {
           if (nums1[i] == nums2[j]) {
               nums1[index++] = nums1[i];
               i ++;
               j ++;
           } else if (nums1[i] > nums2[j]) {
               j ++;
           } else {
               i ++;
           }
       }
       return Arrays.copyOfRange(nums1, 0, index);
}
}

 

leetcode350:两个数组的交集Ⅱ

原文:https://www.cnblogs.com/liushoudong/p/13492594.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!