「这是我参与2022首次更文挑战的第23天,活动详情查看:2022首次更文挑战」。
题目描述🌍
给定两个数组 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
哈希表法🔍
解题思路
将 nums1 数组转为哈希集合,然后逐个判断 nums2 数组中的元素是否已经存在于哈希集合中,存在则表示该元素为两数组的交集元素;将该元素存入另一个 HashSet,从而保证交集元素不会重复。
注:哈希集合判断元素是否存在的操作 contains() 耗时 .
代码
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()};
}
};
时间复杂度:,m 为 nums1 长度,n 为 nums2 长度
空间复杂度:
排序 & 双指针🚀
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;
}
};
时间复杂度:,m, n 分别是两数组的长度
空间复杂度:
知识点🌓
「Java」HashSet 转 int[]
(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」 仓库,欢迎随时加入我们的刷题小分队!