【排序-简单】350. 两个数组的交集 II

博客围绕计算两个数组交集展开,给出Python代码实现,包括不排序直接处理和使用Counter方法。还探讨了进阶问题,如数组已排序时的算法优化、nums1比nums2小很多时的最优方法,以及nums2存于磁盘且内存有限时的解决方案,推荐相关数据库文章。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【题目】
给定两个数组,编写一个函数来计算它们的交集。
示例 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 的元素存储在磁盘上,内存是有限的,并且你不能一次加载所有的元素到内存中,你该怎么办?
【代码】
【Python】
【方法1】不排序直接处理num1,对其中的字符数量进行统计。

class Solution:
    def intersect(self, nums1: List[int], nums2: List[int]) -> List[int]:
        rs=[]
        cnt={}
        for n in nums1:
            if n not in cnt:
                cnt[n]=0
            cnt[n]+=1
        for n in nums2:
            if n in cnt and cnt[n]:
                cnt[n]-=1
                rs.append(n)
        return rs

【方法2】Counter

class Solution:
    def intersect(self, nums1: List[int], nums2: List[int]) -> List[int]:
        rs=[]
        nums1=dict(Counter(nums1))
        nums2=dict(Counter(nums2))
        print(nums2)
        for i in nums2:
            if i in nums1:
                rs.extend([i]*min(nums1[i],nums2[i]))
        return rs

关于进阶部分的三问,面对提出的三种情况给出下面的对策:
【一问】如果给定的数组已经排好序呢?你将如何优化你的算法?

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

【二问】如果 nums1 的大小比 nums2 小很多,哪种方法更优?
可以使用方法2中的代码,对其简单的改动即可
首先,对nums1,nums2进行处理,对其中的字符进行统计存储在dict中;
然后,选取较小长度的dict作为主元素,遍历这个dict,对于每个key查询,看其是否在dict2中存在,如果存在,则选取二者value的最小值。将该元素加入rs列表中。

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

  • 解决方案:通过归并外排将两个数组排序后再使用排序双指针查找

对应进阶问题三,如果内存十分小,不足以将数组全部载入内存,那么必然也不能使用哈希这类费空间的算法,只能选用空间复杂度最小的算法,即【一问】。
但是【一问】中需要改造,一般说排序算法都是针对于内部排序,一旦涉及到跟磁盘打交道(外部排序),则需要特殊的考虑。归并排序是天然适合外部排序的算法,可以将分割后的子数组写到单个文件中,归并时将小文件合并为更大的文件。当两个数组均排序完成生成两个大文件后,即可使用双指针遍历两个文件,如此可以使空间复杂度最低。
关于外部排序与JOIN,强烈推荐大家看一下 数据库内核杂谈(六):表的 JOIN(连接)这一系列数据库相关的文章
参考:https://leetcode-cn.com/problems/intersection-of-two-arrays-ii/solution/jin-jie-san-wen-by-user5707f/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值