Skip to content

一、问题描述

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

示例:

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

提示:

  • 每个输入数组中只有一个数字。
  • 两个数组不会有公共元素。

二、方案一:使用哈希集合

1、思路

使用哈希集合来解决这个问题。首先,我们将一个数组转换成哈希集合,然后遍历另一个数组,检查元素是否在哈希集合中。如果在,并且结果集中还没有这个元素,我们就将其添加到结果集中

2、代码实现

go
func intersection(nums1 []int, nums2 []int) []int {
    set1 := map[int]bool{}
    set2 := map[int]bool{}
    for _, num := range nums1 {
        set1[num] = true
    }
    for _, num := range nums2 {
        set2[num] = true
    }
    result := []int{}
    for num := range set1 {
        if set2[num] {
            result = append(result, num)
        }
    }
    return result
}

3、复杂度分析

  • 时间复杂度:O(m + n),其中 m 和 n 分别是两个数组的长度。
  • 空间复杂度:O(m + n),用于存储两个数组的哈希集合。

三、方案二:排序和双指针

1、思路

如果两个数组是有序的,我们可以使用双指针方法来找到它们的交集。首先,对两个数组进行排序,然后使用两个指针分别遍历两个数组。如果两个指针指向的元素相同,那么这个元素就是交集的一部分。如果不同,我们就移动指向较小元素的指针。

2、代码实现

go
func intersection(nums1 []int, nums2 []int) []int {
	sort.Ints(nums1)
	sort.Ints(nums2)
	var res []int
	i, j := 0, 0
	for i < len(nums1) && j < len(nums2) {
		if nums1[i] == nums2[j] {
			// 去除重复元素
			if len(res) == 0 || nums1[i] > res[len(res)-1] {
				res = append(res, nums1[i])
			}
			i++
			j++
		} else if nums1[i] < nums2[j] {
			i++
		} else {
			j++
		}
	}

	return res
}

3、复杂度分析

  • 时间复杂度:O(m log m + n log n),其中 m 和 n 分别是两个数组的长度,排序的时间复杂度是 O(log n)。
  • 空间复杂度:O(1),不需要额外的空间。

四、总结

方案时间复杂度空间复杂度备注
哈希集合O(m + n)O(m + n)适用于数组无序或元素重复较多的情况
排序和双指针O(m log m + n log n)O(1)适用于数组有序且元素重复较少的情况

根据数组的特性和对时间、空间复杂度的需求,可以选择合适的方案。

木川工作室 (微信:mcmc2024)