• leetcode350:两个数组的交集Ⅱ


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

    示例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);
    }
    }
  • 相关阅读:
    解决VM 安装Ubuntu64与 Device/Credential Guard 不兼容,显示不支持64位系统
    WPF处理内容溢出
    .NET Standard 2.0 是什麼?可以吃嗎?
    C#.Net]启动外部程序的几种常用方法汇总
    在C#中接收系统屏幕锁定和解锁的事件
    C#.Net]启动外部程序的几种常用方法汇总
    MongoDB索引的使用
    读取xml并将节点保存到Excal
    开学后的第一篇
    续并查集学习笔记——Gang团伙题解
  • 原文地址:https://www.cnblogs.com/liushoudong/p/13492594.html
Copyright © 2020-2023  润新知