「这是我参与11月更文挑战的第5天,活动详情查看:2021最后一次更文挑战」
背景
比较巧的是在刷到LeetCode299题的时候,没过几天就刷到这个题目,里面的思路有联系,虽然这是一个简单题,但我觉得这个是一个比较有意义的题目,因此写一篇文章进行记录。
题目
给定两个数组,编写一个函数来计算它们的交集。
示例 1:
输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2,2]
示例 2:
输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出:[4,9]
说明:
输出结果中每个元素出现的次数,应与元素在两个数组中出现次数的最小值一致。
我们可以不考虑输出结果的顺序。
来源:力扣(LeetCode)
链接:leetcode-cn.com/problems/in…
思路
两种方案:哈希表和双指针
官方解析(可惜没有JavaScript的):
leetcode-cn.com/problems/in…
代码以及代码分析
哈希表:
执行用时:104 ms, 在所有 JavaScript 提交中击败了5.32%的用户
内存消耗:40.1 MB, 在所有 JavaScript 提交中击败了14.43%的用户
参数是两个数组,首先定义一个哈希表,let m = new Map(),定义两个数组arr1是长度小的数组,arr2是长度大的数组,这个地方先进行判断,长度小的拷贝到arr1,长度大的拷贝到arr2。还需要定义一个res空数组。
接下来,把nums1用哈希表映射,这个循环先把哈希表元素对应的元素获取到,然后校验哈希表中是否有这个键值对,如果有就把k自增,然后就进行修改,如果没有这个键就新建,值默认为1.
随后遍历num2,找到一个哈希表对应的数少一个,在短数组中找到长数组的元素。咱们来看代码。temp暂存在arr1中找到arr2的下标结果。如果找到而且arr1的值还有(即大于0),则res数组添加这个,然后获取到k的值进行自减。最后res是我们要的结果。
双指针
执行用时: 76 ms, 在所有 JavaScript 提交中击败了62 .14 % 的用户
内存消耗: 40 MB, 在所有 JavaScript 提交中击败了17 .92 % 的用户
先定义两个数组存储参数排序后的结果,这里的sort用的是sort((a, b) => a - b),原因在之前文章中有提到。再定义res结果空数组,初始化左右指针为0.
用while循环,条件是left < arr1.length 并且 right < arr2.length,如果arr1和arr2相等了就把这个相等的值加到res数组里面,两个指针都移动。如果arr1[left] 大于 arr2[right]就right++,反之就left++,循环结束后的res就是我们需要的结果数组。
//方案1
var intersect = function (nums1, nums2) {
let m = new Map();
let arr1 = [];
let arr2 = [];
if (nums1.length > nums2.length) {
arr1 = [...nums2];
arr2 = [...nums1];
} else {
arr1 = [...nums1];
arr2 = [...nums2];
}
let res = [];
// 1
for (let i = 0; i < arr1.length; i++) {
let k = m.get(arr1[i]);
if (m.has(arr1[i])) {
k++;
m.set(arr1[i], k)
} else {
m.set(arr1[i], 1)
}
}
// 2
for (let i = 0; i < arr2.length; i++) {
let temp = arr1.indexOf(arr2[i]);
if (temp !== -1 && m.get(arr1[temp]) > 0) {
res.push(arr1[temp]);
let k = m.get(arr1[temp]);
k--;
m.set(arr1[temp], k);
}
}
console.log(res);
};
intersect([1, 2, 2, 1], [2, 2])
//方案2
var intersect = function (nums1, nums2) {
let arr1 = [...nums1].sort((a, b) => a - b);
let arr2 = [...nums2].sort((a, b) => a - b);
let left = 0;
let right = 0;
let res = []
while (left < arr1.length && right < arr2.length) {
if (arr1[left] === arr2[right]) {
res.push(arr1[left])
left++
right++
} else if (arr1[left] > arr2[right]) {
right++
} else left++
}
console.log(res);
};
intersect([43, 85, 49, 2, 83, 2, 39, 99, 15, 70, 39, 27, 71, 3, 88, 5, 19, 5, 68, 34, 7, 41, 84, 2, 13, 85, 12,
54, 7, 9, 13, 19, 92
], [10, 8, 53, 63, 58, 83, 26, 10, 58, 3, 61, 56, 55, 38, 81, 29, 69, 55, 86, 23, 91, 44, 9, 98, 41, 48,
41, 16, 42, 72, 6, 4, 2, 81, 42, 84, 4, 13
])
// [2,83,3,41,84,13,9]
说明
本文是作者用于学习时,在LeetCode刷题所见所想,引用了部分力扣资源,代码是根据大佬们思路进行写的,比起大佬们的代码,我的代码肯定有很大的优化空间了,如果是学习的建议访问力扣官网进行学习,本博客仅记录我的成长过程