返回

**剑指 Offer 350:两个数组的交集 II(掌握三种解法,助你轻松过关!)**

前端

  1. 双指针法:简单高效,轻松上手

双指针法是一种简单而有效的算法,特别适用于处理两个已排序的数组。它的核心思想是使用两个指针来遍历两个数组,比较它们当前指向的元素的大小,并根据比较结果更新指针的位置。如果两个元素相等,则将它们加入到交集数组中。

def intersect(nums1, nums2):
    """
    :type nums1: List[int]
    :type nums2: List[int]
    :rtype: List[int]
    """
    # Sort the arrays in ascending order
    nums1.sort()
    nums2.sort()

    # Initialize two pointers
    i = 0
    j = 0

    # Create an empty list to store the intersection
    intersection = []

    # While both pointers are within the bounds of their respective arrays
    while i < len(nums1) and j < len(nums2):
        # If the current elements are equal
        if nums1[i] == nums2[j]:
            # Add the element to the intersection list
            intersection.append(nums1[i])

            # Increment both pointers
            i += 1
            j += 1
        # If the current element of nums1 is less than the current element of nums2
        elif nums1[i] < nums2[j]:
            # Increment the pointer of nums1
            i += 1
        # If the current element of nums1 is greater than the current element of nums2
        else:
            # Increment the pointer of nums2
            j += 1

    # Return the intersection list
    return intersection

2. 哈希表法:快速查询,适用性广

哈希表法是一种更通用的算法,可以处理未排序的数组。它的核心思想是使用一个哈希表来存储第一个数组中的元素。然后,遍历第二个数组,检查每个元素是否在哈希表中。如果存在,则将该元素加入到交集数组中。

def intersect(nums1, nums2):
    """
    :type nums1: List[int]
    :type nums2: List[int]
    :rtype: List[int]
    """
    # Create a hash table to store the elements of nums1
    hash_table = {}
    for num in nums1:
        # If the number is not in the hash table, add it with a count of 1
        if num not in hash_table:
            hash_table[num] = 1
        # If the number is already in the hash table, increment its count
        else:
            hash_table[num] += 1

    # Create an empty list to store the intersection
    intersection = []

    # Iterate over nums2
    for num in nums2:
        # If the number is in the hash table and its count is greater than 0
        if num in hash_table and hash_table[num] > 0:
            # Add the element to the intersection list
            intersection.append(num)

            # Decrement the count of the number in the hash table
            hash_table[num] -= 1

    # Return the intersection list
    return intersection

3. 排序后的优化算法:极致性能,特殊情况利器

如果给定的数组已经排好序,我们可以使用一种更快的算法来求交集。它的核心思想是使用两个指针来遍历两个数组,比较它们当前指向的元素的大小,并根据比较结果更新指针的位置。如果两个元素相等,则将它们加入到交集数组中。由于数组已排序,因此我们可以使用二分查找来确定元素是否存在于另一个数组中,从而进一步优化算法的性能。

def intersect(nums1, nums2):
    """
    :type nums1: List[int]
    :type nums2: List[int]
    :rtype: List[int]
    """
    # Sort the arrays in ascending order
    nums1.sort()
    nums2.sort()

    # Initialize two pointers
    i = 0
    j = 0

    # Create an empty list to store the intersection
    intersection = []

    # While both pointers are within the bounds of their respective arrays
    while i < len(nums1) and j < len(nums2):
        # If the current elements are equal
        if nums1[i] == nums2[j]:
            # Add the element to the intersection list
            intersection.append(nums1[i])

            # Increment both pointers
            i += 1
            j += 1
        # If the current element of nums1 is less than the current element of nums2
        elif nums1[i] < nums2[j]:
            # Use binary search to find the current element of nums1 in nums2
            index = binary_search(nums2, j, len(nums2) - 1, nums1[i])

            # If the element is found, increment both pointers
            if index != -1:
                i += 1
                j = index + 1
            # If the element is not found, increment the pointer of nums1
            else:
                i += 1
        # If the current element of nums1 is greater than the current element of nums2
        else:
            # Use binary search to find the current element of nums2 in nums1
            index = binary_search(nums1, i, len(nums1) - 1, nums2[j])

            # If the element is found, increment both pointers
            if index != -1:
                j += 1
                i = index + 1
            # If the element is not found, increment the pointer of nums2
            else:
                j += 1

    # Return the intersection list
    return intersection


def binary_search(nums, start, end, target):
    """
    Performs binary search on the given array to find the target element.

    :param nums: The array to search in.
    :param start: The starting index of the search range.
    :param end: The ending index of the search range.
    :param target: The target element to search for.

    :returns: The index of the target element if found, or -1 if not found.
    """
    while start <= end:
        mid = (start + end) // 2

        if nums[mid] == target:
            return mid
        elif nums[mid] < target:
            start = mid + 1
        else:
            end = mid - 1

    return -1

结语

剑指 Offer 350: 两个数组的交集 II 是一道经典的算法题目,它考验了我们的算法设计能力和编码水平。通过学习这三种不同的解法,你将能够更好地理解算法的本质,并能够根据不同的场景选择最合适的算法来解决问题。希望这篇文章能够帮助你轻松过关,并在未来的编程之旅中披荆斩棘!