「LeetCode」349.两个数组的交集

608 阅读2分钟

「这是我参与2022首次更文挑战的第23天,活动详情查看:2022首次更文挑战」。

题目描述🌍

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

示例 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

哈希表法🔍

解题思路

nums1 数组转为哈希集合,然后逐个判断 nums2 数组中的元素是否已经存在于哈希集合中,存在则表示该元素为两数组的交集元素;将该元素存入另一个 HashSet,从而保证交集元素不会重复。

:哈希集合判断元素是否存在的操作 contains() 耗时 O(1)O(1).

代码

Java

class Solution {
    public int[] intersection(int[] nums1, int[] nums2) {
        Set<Integer> hashSet = new HashSet<>();
        for (int num1 : nums1) {
            hashSet.add(num1);
        }
        HashSet<Integer> intersection = new HashSet<>();
        for (int num2 : nums2) {
            if (hashSet.contains(num2))
                intersection.add(num2);
        }
        // 该转换方式多耗费 n·ms
//        int[] intersection = intersec.stream().mapToInt(Number::intValue).toArray();
//        return intersection;
        int[] result = new int[intersection.size()];
        int i = 0;
        for (int num: intersection){
            result[i++] = num;
        }
        return result;
    }
}

C++

class Solution {
public:
    vector<int> intersection(vector<int> &nums1, vector<int> &nums2) {
        unordered_set<int> temp;
        for (int num: nums1) {
            temp.insert(num);
        }
        unordered_set<int> intersection;
        for (int num: nums2) {
            if (temp.find(num) != temp.end()) {
                intersection.insert(num);
            }
        }
        // unordered_set<int> ==> vector<int>
        return vector<int>{intersection.begin(), intersection.end()};
    }
};

时间复杂度:O(m+n)O(m+n),m 为 nums1 长度,n 为 nums2 长度

空间复杂度:O(m+n)O(m+n)

排序 & 双指针🚀

Q:如果不借助 HashSet 怎么求取交集呢?又怎么确保交集中的元素是唯一的呢?

解题思路

将两个数组排序后,对比两个指针指向元素的大小,若某一方偏小,则推进该指针;直至两个元素大小相等,此时还需要避免添加连续重复的交集元素,所以借助 while 循环跳过某一方数组的连续重复元素。

代码

Java

class Solution {
    public int[] intersection(int[] nums1, int[] nums2) {
        Arrays.sort(nums1);
        Arrays.sort(nums2);

        int len1 = nums1.length, len2 = nums2.length;
        int i = 0, i1 = 0, i2 = 0;
        // 交集元素个数不会超过任何一个数组
        int[] intersection = new int[len1];

        while (i1 < len1 && i2 < len2) {
            if (nums1[i1] < nums2[i2]) {
                i1++;
            } else if (nums1[i1] > nums2[i2]) {
                i2++;
            } else {
                // 找到并添加交集元素
                intersection[i] = nums1[i1];
                // 确保交集元素不会重复
                while (i1 < len1 && nums1[i1] == intersection[i]) {
                    i1++;
                }
                i++;
                i2++;
            }
        }

        return Arrays.copyOfRange(intersection, 0, i);
    }
}

C++

class Solution {
public:
    vector<int> intersection(vector<int> &nums1, vector<int> &nums2) {
        sort(nums1.begin(), nums1.end());
        sort(nums2.begin(), nums2.end());
        int len1 = nums1.size(), len2 = nums2.size();
        int i = 0, i1 = 0, i2 = 0;
        vector<int> intersection;
        while (i1 < len1 && i2 < len2) {
            if (nums1[i1] < nums2[i2]) {
                i1++;
            } else if (nums1[i1] > nums2[i2]) {
                i2++;
            } else {
                intersection.push_back(nums1[i1]);
                while (i1 < len1 && nums1[i1] == intersection[i]) {
                    ++i1;
                }
                ++i;
                ++i2;
            }
        }
        return intersection;
    }
};

时间复杂度:O(mlogm+nlogn)O(m·logm+n·logn),m, n 分别是两数组的长度

空间复杂度:O(logm+logn)O(logm+logn)

知识点🌓

「Java」HashSetint[]

(1)逐个赋值

HashSet<Integer> intersection = new HashSet<>();
int[] result = new int[intersection.size()];
int i = 0;
for (int num: intersection) {
    result[i++] = num;
}

(2)借用 stream

int[] intersection = intersec.stream().mapToInt(Number::intValue).toArray();

最后🌅

该篇文章为 「LeetCode」 系列的 No.21 篇,在这个系列文章中:

  • 尽量给出多种解题思路
  • 提供题解的多语言代码实现
  • 记录该题涉及的知识点

👨‍💻争取做到 LeetCode 每日 1 题,所有的题解/代码均收录于 「LeetCode」 仓库,欢迎随时加入我们的刷题小分队!