Python面试宝典第36题:数组的交集

36 篇文章 0 订阅 ¥19.90 ¥99.00

题目

        给定两个数组nums1和nums2,返回它们的交集 。输出结果中的每个元素一定是唯一的,我们可以不考虑输出结果的顺序。

        示例 1:

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

        示例 2:

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

哈希法

        使用哈希法求解两个数组的交集是一个非常高效的方法,其基本思想为:使用哈希表(或集合)存储一个数组中的所有元素,然后遍历另一个数组,检查其中的元素是否出现在哈希表中。使用哈希法求解本题的主要步骤如下。

        1、创建哈希表。遍历第一个数组nums1,将所有元素添加到哈希表中。

        2、查找交集。遍历第二个数组nums2,检查每个元素是否在哈希表中。

        3、收集结果。如果元素存在于哈希表中,则将其添加到结果列表中。同时,从哈希表中移除该元素,以避免重复添加。

        4、返回收集到的结果列表。

        根据上面的算法步骤,我们可以得出下面的示例代码。

def array_intersection_by_hash(nums1, nums2):
    result = []
    # 使用集合存储nums1中的元素
    hash_set = set(nums1)

    # 遍历nums2中的每个元素
    for num in nums2:
        # 如果元素存在于哈希表中
        if num in hash_set:
            # 添加到结果列表中
            result.append(num)
            # 从哈希表中移除该元素,以避免重复
            hash_set.remove(num)

    return result

nums1 = [1, 2, 2, 1]
nums2 = [2, 2]
print(array_intersection_by_hash(nums1, nums2))

nums1 = [4, 9, 5]
nums2 = [9, 4, 9, 8, 4]
print(array_intersection_by_hash(nums1, nums2))

双指针法

        使用双指针法求解两个数组的交集也是一种效率较高的方法,尤其是在两个数组都已经排序的情况下。对于两个已排序的数组,可以通过双指针法找到它们的交集。这种方法的核心是:同时维护两个指针,一个指向第一个数组中的元素,另一个指向第二个数组中的元素。通过比较这两个指针所指向的元素值,可以有效地找到交集中的元素。使用双指针法求解本题的主要步骤如下。

        1、排序数组。如果输入数组未排序,则先对两个数组进行排序。

        2、分别为两个数组初始化指针i和j。

        3、比较元素。比较两个指针所指向的元素,进行以下操作。

        (1)如果两个元素相等,且该元素不同于上一个加入结果集的元素,则加入结果集。

        (2)如果nums1[i] < nums2[j],则移动nums1的指针i。

        (3)如果nums1[i] > nums2[j],则移动nums2的指针j。

        4、继续遍历。重复步骤3,直到遍历完任一阵列。

        5、返回收集到的结果列表。

        根据上面的算法步骤,我们可以得出下面的示例代码。

def array_intersection_by_two_pointers(nums1, nums2):
    result = []
    # 先对两个数组进行排序
    nums1.sort()
    nums2.sort()

    # 初始化两个指针
    i, j = 0, 0
    # 用于记录上一个加入结果集的元素
    prev = None

    # 遍历两个数组直到有一个数组遍历结束
    while i < len(nums1) and j < len(nums2):
        if nums1[i] == nums2[j]:
            # 如果当前元素与上一个加入结果集的元素不同,则加入结果集
            if nums1[i] != prev:
                result.append(nums1[i])
                prev = nums1[i]
            # 移动两个指针
            i += 1
            j += 1
        elif nums1[i] < nums2[j]:
            # 移动nums1的指针
            i += 1
        else:
            # 移动nums2的指针
            j += 1

    return result

nums1 = [1, 2, 2, 1]
nums2 = [2, 2]
print(array_intersection_by_two_pointers(nums1, nums2))

nums1 = [4, 9, 5]
nums2 = [9, 4, 9, 8, 4]
print(array_intersection_by_two_pointers(nums1, nums2))

内置函数

        实际上,我们还可以使用Python的内置函数来求解本题。其原理与上面介绍的哈希法基本类似,这里就不再赘述了。使用内置函数求解本题的示例代码如下。

def array_intersection_by_builtin_func(nums1, nums2):
    return list(set(nums1) & set(nums2))

nums1 = [1, 2, 2, 1]
nums2 = [2, 2]
print(array_intersection_by_builtin_func(nums1, nums2))

nums1 = [4, 9, 5]
nums2 = [9, 4, 9, 8, 4]
print(array_intersection_by_builtin_func(nums1, nums2))

总结

        使用哈希法求解本题时,构建哈希表的时间复杂度为O(n),遍历查找的时间复杂度为O(m),故总体时间复杂度为O(n + m)。其中,n是nums1的长度,m是nums2的长度。哈希法的优点是实现简单,且不依赖于输入数组是否有序。

        使用双指针法求解本题时,排序的时间复杂度为O(n*logn) + O(m*logm),双指针遍历的时间复杂度为O(n + m),故总体时间复杂度为O(n*logn + m*logm)。对于排序后的数组,可以直接使用双指针法进行高效的查找。但其实现稍微复杂一些,需要考虑边界条件等各自情况。

💡 需要《Python面试宝典》完整源码的大佬们,可订阅专栏后,搜索微信公众号“希望睿智”私信获取。

  • 18
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

希望_睿智

您的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值