1. 题目描述
给定两个数组nums1和nums2,返回它们的交集。输出结果中的每个元素一定是唯一的。我们可以不考虑输出结果的顺序。
示例1:
输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2]
题目条件:
- 1 <= nums1.length, nums2.length <= 1000
- 0 <= nums1[i], nums2[i] <= 1000
2. 解题思路
2.1 数组比较法(适用于题目条件限制了数组范围和元素范围的情况)
- 定义一个空数组cuontnums用于存储较短的那个数组中元素出现次数
- 遍历另一个数组的元素,看是否在countnums中存在,如果存在则放入结果数组,并把countnums中对应元素清零(防止重复)
- 返回结果数组
2.2 哈希表法(适用于任意整数元素范围的情况)
哈希表相比固定数组的优势是哈希表可以处理任意整数,而不仅仅是0到1000之间的数,这样更灵活。原来的方法有潜在越界风险,哈希表能解决这个问题。但同时,带来了一定的复杂度,这一部分用C++中的unorder_set来实现,如果用C语言则需要导入第三方库(如 uthash),因为C语言没有原生的unordered_set。
哈希表实现逻辑如下:
- 定义哈希表结构体:存储数字及其出现次数。
- 统计 nums1 的元素:将 nums1 中的数字插入哈希表,记录出现次数。
- 遍历 nums2 检查交集:若数字存在于哈希表中,则加入结果数组,并根据需求减少计数(支持重复)或删除键(去重)。
- 动态管理内存:释放哈希表内存
3. 代码实现(C语言)
3.1 数组比较法
int* intersection(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize) {int countnums[1001] = {0}; // 统计nums1中数字出现的次数(题目条件:元素值范围0~1000)int lesssize = nums1Size < nums2Size ? nums1Size : nums2Size; //找到更短的数组,这是最大交集长度int *result = (int*)calloc(lesssize, sizeof(int)); //动态分配内存空间并初始化为0int resultindex = 0;for(int i = 0; i < nums1Size; i++){countnums[nums1[i]]++; //遍历nums1,统计每个数字出现的次数到countnums1中}for(int i = 0; i < nums2Size; i++){//遍历nums2,若 nums2[i] 在 nums1 中存在(计数>0),//如果存在,就将该数字添加到结果数组,并增加结果索引//同时将countnums1对应的位置设为0,避免重复添加。if(countnums[nums2[i]] > 0){result[resultindex] = nums2[i];resultindex++;countnums[nums2[i]] = 0; }}*returnSize = resultindex;return result;
}
有一个点说明的是,如果不考虑去除交集中的重复,countnums[nums2[i]] = 0改为 countnums[nums2[i]]- - 即可。
3.2哈希表法
C++实现
class Solution {
public:vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {unordered_set<int> result_set; // 存放结果,之所以用set是为了给结果集去重unordered_set<int> nums_set(nums1.begin(), nums1.end());for (int num : nums2) {// 发现nums2的元素 在nums_set里又出现过if (nums_set.find(num) != nums_set.end()) {result_set.insert(num);}}return vector<int>(result_set.begin(), result_set.end());}
};