📜  两个数组的并集 leetcode - C++ (1)

📅  最后修改于: 2023-12-03 15:21:33.769000             🧑  作者: Mango

两个数组的并集 LeetCode - C++

简介

本文将介绍 LeetCode 上的「两个数组的并集」问题,并提供 C++ 的解决方案。下面我们将逐步解析这个问题并提供可行的解决方案。

问题描述

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

示例
输入: nums1 = [1,2,2,1], nums2 = [2,2]
输出: [2]
输入: nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出: [9,4]
解法
方法一 (哈希表)

最直接的做法是使用哈希表存储 nums1 中的数字及其出现的次数,然后遍历 nums2,如果数字在哈希表中出现过,则将其添加到答案并减小哈希表中该数字出现次数的值。

代码实现如下:

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        unordered_map<int, int> m;
        vector<int> res;
        for (auto num : nums1) {
            m[num]++;
        }
        for (auto num : nums2) {
            if (m[num] > 0) {
                res.push_back(num);
                m[num]--;
            }
        }
        return res;
    }
};

复杂度分析

  • 时间复杂度:$O(n + m)$,其中 $n$ 和 $m$ 分别为 nums1nums2 的长度。使用两个哈希集合分别存储两个数组,每个集合的插入操作的时间复杂度为 $O(n)$,其中 $n$ 为对应数组的长度。而哈希集合的查询操作的时间复杂度最坏为 $O(n)$,因此总时间复杂度为 $O(n + m)$。
  • 空间复杂度:$O(n + m)$,其中 $n$ 和 $m$ 分别为 nums1nums2 的长度。空间复杂度主要取决于两个哈希集合。
方法二 (排序 + 双指针)

对两个数组进行排序,然后使用双指针的方法找到它们的公共元素。

具体来说,首先对两个数组进行排序,然后使用两个指针遍历两个数组。初始时,两个指针分别指向两个数组的头部,并依次将两个指针指向的数字进行比较,如果相等,则将该数字添加到答案并将两个指针同时右移;如果不相等,则将指向较小数字的指针右移一位。

代码实现如下:

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        sort(nums1.begin(), nums1.end());
        sort(nums2.begin(), nums2.end());
        int i = 0, j = 0;
        vector<int> res;
        while (i < nums1.size() && j < nums2.size()) {
            if (nums1[i] < nums2[j]) {
                i++;
            } else if (nums1[i] > nums2[j]) {
                j++;
            } else {
                if (res.empty() || res.back() != nums1[i]) {
                    res.push_back(nums1[i]);
                }
                i++;
                j++;
            }
        }
        return res;
    }
};

复杂度分析

  • 时间复杂度:$O(n\log n + m\log m)$,其中 $n$ 和 $m$ 分别为 nums1nums2 的长度。对两个数组排序的时间复杂度分别为 $O(n\log n)$ 和 $O(m\log m)$,双指针寻找公共元素的时间复杂度为 $O(n + m)$,因此总时间复杂度为 $O(n\log n + m\log m)$。
  • 空间复杂度:$O(\min(n, m))$,其中 $n$ 和 $m$ 分别为 nums1nums2 的长度。为返回值创建一个数组 res,数组长度为 $\min(n, m)$,因此空间复杂度为 $O(\min(n, m))$。不过我们可以忽略创建数组的空间,因为存储答案不属于算法的空间复杂度。如果在使用排序的语言中使用语言内置的排序函数,则不需要考虑排序的空间复杂度。
总结

本文详细介绍了 LeetCode 上的「两个数组的并集」问题,并提供了哈希表和排序 + 双指针两种解决方案。较为复杂的哈希表解法相对简单,且有较好的时空复杂度。而排序 + 双指针方法则更为优秀,时间复杂度与相对更低的空间复杂度使其成为更优秀的算法实现。

关于其他问题和更多解法,请参见LeetCode。