【刷题打卡】349. 两个数组的交集

100 阅读1分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第11天,点击查看活动详情

一、题目描述:

349. 两个数组的交集 - 力扣(LeetCode) (leetcode-cn.com)

给定两个数组 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.length, nums2.length <= 1000
  • 0 <= nums1[i], nums2[i] <= 1000

二、思路分析:

对于两个有序数组,我们想要求数组的交集是一件相对容易的事情,所以我们先将两个数组进行排序。

接下来我们遍历数组 A,然后使用指针在数组 B 上扫描,寻找 A 中元素出现在 B 中位置。

因为 A 是有序的,我们在 B 中要查找的 A 元素应该越来越大,同时又因为 B 也是有序的,所以在查找的过程中存在 3 种情况:

  • 当 B 当前指向元素小于 A 中当前元素时,我们需要将 B 中指针向后移动,寻找 B 中更大的元素与 A 元素配对,循环。
  • 当 B 当前指向元素等于 A 中当前元素时,找到了 A 与 B 共有元素,终止。
  • 当 B 当前指向元素大于 A 中当前元素时,此时 B 中无对应元素与 A 当前元素配对,终止。

我们可以发现在整个过程中,我们遍历了数组 A、同时数组 B 中指针只会单调向后移动,所以遍历与指针扫描的复杂度为 O(n+m)O(n + m)

三、AC 代码:

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        sort(nums1.begin(), nums1.end());
        sort(nums2.begin(), nums2.end());
        
        vector<int> ans;
        for (int i = 0, j = 0, n = nums1.size(), m = nums2.size(); i < n; i++){
            if (i > 0 && nums1[i] == nums1[i - 1]) continue;
            while(j < m && nums2[j] < nums1[i]) ++j;
            if (j < m && nums2[j] == nums1[i]) ans.push_back(nums1[i]);
        }

        return ans;
    }
};

范文参考

349. 两个数组的交集(C++「BF法+Set法」AC) - 两个数组的交集 - 力扣(LeetCode)