掘金团队号上线,助你 Offer 临门! 点击 查看详情
一、题目描述:
给定两个数组,编写一个函数来计算它们的交集。
示例 1:
输入:nums1 = [1,2,2,1], nums2 = [2,2] 输出:[2]
示例 2:
输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4] 输出:[9,4]
说明:
输出结果中的每个元素一定是唯一的。 我们可以不考虑输出结果的顺序。 通过次数170,589提交次数231,686
二、思路分析:
思路1(失败):
先将两个数组分别进行排序,得到两个新数组arr1,arr2,将arr1通过join('')转为一个字符串,再arr2循环遍历,通过indexOf去查找arr1生成的字符串中时候存在交集,如果有,就push进新定义的一个数组里,最后return出来
执行结果: 失败 代码如下:
var intersection = function(nums1, nums2) {
let arr1 = nums1.sort().join('')
let arr2 = nums2.sort()
let newArr = []
arr2.forEach(item => {
if(arr1.indexOf(item)>-1){
if(newArr.length){
let newArrString = newArr.join('')
if(newArrString.indexOf(item) == -1 ) newArr.push(item)
}else{
newArr.push(item)
}
}
})
return newArr
};
思路2(成功):
先将两个数组去重并排序,得到两个新数组arr1,arr2,利用两个循环去判断,生成一个新数组返回
执行结果:通过 代码如下:
var intersection = function(nums1, nums2) {
let arr1 =[...new Set(nums1)].sort()
let arr2 = [...new Set(nums2)].sort()
let newArr = []
arr2.forEach(item => {
for(let i = 0;i<arr1.length;i++){
if(item == arr1[i]) newArr.push(item)
}
})
return newArr
}
改进: 在思路2的基础上运行成功了,但内存消耗有点大,于是我把for循环也改成了forEach,发现内存消耗减少了:
var intersection = function(nums1, nums2) {
let arr1 =[...new Set(nums1)].sort()
let arr2 = [...new Set(nums2)].sort()
let newArr = []
arr2.forEach(item => {
arr1.forEach(item1 => {
if(item == item1) newArr.push(item)
})
})
return newArr
};
还可以用some()方法来进行判断:
var intersection = function(nums1, nums2) {
let arr1 =[...new Set(nums1)].sort()
let arr2 = [...new Set(nums2)].sort()
let newArr = []
arr2.forEach(item => {
if(arr1.some(item1 => {return item1 == item})) newArr.push(item)
})
return newArr
};
三、AC 代码:
var intersection = function(nums1, nums2) {
let arr1 =[...new Set(nums1)].sort()
let arr2 = [...new Set(nums2)].sort()
let newArr = []
arr2.forEach(item => {
for(let i = 0;i<arr1.length;i++){
if(item == arr1[i]) newArr.push(item)
}
})
return newArr
};
官方题解:
方法一:两个集合 计算两个数组的交集,直观的方法是遍历数组 nums1,对于其中的每个元素,遍历数组 nums2 判断该元素是否在数组 nums2 中,如果存在,则将该元素添加到返回值。假设数组 nums1 和 nums2 的长度分别是 mm 和 nn,则遍历数组 nums1 需要 O(m)O(m) 的时间,判断 nums1 中的每个元素是否在数组 nums2 中需要 O(n)O(n) 的时间,因此总时间复杂度是 O(mn)O(mn)。 如果使用哈希集合存储元素,则可以在 O(1)O(1) 的时间内判断一个元素是否在集合中,从而降低时间复杂度。 首先使用两个集合分别存储两个数组中的元素,然后遍历较小的集合,判断其中的每个元素是否在另一个集合中,如果元素也在另一个集合中,则将该元素添加到返回值。该方法的时间复杂度可以降低到 O(m+n)O(m+n)。
const set_intersection = (set1, set2) => {
if (set1.size > set2.size) {
return set_intersection(set2, set1);
}
const intersection = new Set();
for (const num of set1) {
if (set2.has(num)) {
intersection.add(num);
}
}
return [...intersection];
}
var intersection = function(nums1, nums2) {
const set1 = new Set(nums1);
const set2 = new Set(nums2);
return set_intersection(set1, set2);
};
四、总结:
官方的题解里用到了Set的add和has方法,属于ES6的知识点,因为我平时用Set用的少,所以没有想到,于是我恶补了下Set的使用方式:
1、 ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值
2、 通过add()方法向 Set 结构加入成员
3、 Set属性:
-
Set.prototype.constructor:构造函数,默认就是Set函数
-
Set.prototype.size:返回Set实例的成员总数
4、Set方法:
-
Set.prototype.add(value):添加某个值,返回 Set 结构本身
-
Set.prototype.delete(value):删除某个值,返回一个布尔值,表示删除是否
-
Set.prototype.has(value):返回一个布尔值,表示该值是否为Set的成员
-
Set.prototype.clear():清除所有成员,没有返回值
想了解更多,可以参考这个:es6.ruanyifeng.com/#docs/set-m…
本文正在参与掘金团队号上线活动,点击 查看大厂春招职位