第 59 题:给定两个数组,写一个方法来计算它们的交集
例如:给定 nums1 = [1, 2, 2, 1],nums2 = [2, 2],返回 [2, 2]。
var nums1 = [1, 2, 2, 1], nums2 = [2, 2, 3, 4]; // 1. // 有个问题, [NaN].indexOf(NaN) === -1 var newArr1 = nums1.filter(function(item) { return nums2.indexOf(item) > -1; }); console.log(newArr1); // 2. var newArr2 = nums1.filter((item) => { return nums2.includes(item); }); console.log(newArr2);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(59)
const intersection = (...arg) => {
return arg[0].filter((item, index) => {
const res = arg[1].indexOf(item);
if(res > -1) {
arg[1].splice(res, 1);
}
return res > -1;
})
};
https://www.zhihu.com/question/19863166
// const num1 = [1, 2, 2, 1]
// const num2 = [2, 2]
// var num1 = [1]
// var num2 = [1,1]
// var num1 = [1,1]
// var num2 = [1]
// var num1 = [61,24,20,58,95,53,17,32,45,85,70,20,83,62,35,89,5,95,12,86,58,77,30,64,46,13,5,92,67,40,20,38,31,18,89,85,7,30,67,34,62,35,47,98,3,41,53,26,66,40,54,44,57,46,70,60,4,63,82,42,65,59,17,98,29,72,1,96,82,66,98,6,92,31,43,81,88,60,10,55,66,82,0,79,11,81]
// var num2 = [5,25,4,39,57,49,93,79,7,8,49,89,2,7,73,88,45,15,34,92,84,38,85,34,16,6,99,0,2,36,68,52,73,50,77,44,61,48]
测试用例通过
hhh 脑子里第一时间想到了这个
function getRes(a,b) {
let res = []
for(let i = 0; i < a.length; i++) {
b.indexOf(a[i]) > -1 && res.push(a[i]) && b.splice(b.indexOf(a[i]), 1);
}
return res;
}
const intersection = (aArray, bArray) => {
const bArraySet = new Set(bArray);
const resultArray = aArray.filter(item => bArraySet.has(item));
return Array.from(resultArray);
}
function commonArray(m, n) {
if (m.length <= n.length) {
return m.filter((v) => n.indexOf(v) !== -1);
} else {
return n.filter((v) => m.indexOf(v) !== -1);
}
}
可以用Set
数组求交集:
let result = [...new Set(arr)].filter( item => new Set(arr2).has(item));
数组求并集:
let union = [...new Set([...arr,...arr2])]
数组求差集:
let diff = [...new Set(arr)].filter( item => !(new Set(arr2).has(item)));
传入两个数组,支持引用类型和NaN,使用map
利用引用计数,复杂度O(n)?
不会算法的我流下了泪水。交集就是你有我也有没错昂。
下面都是代码,格式不太会搞。。。
时间复杂度为On(n是较短数组的长度)
function fn(arr1, arr2) {
if (!arr1 && !arr2) return
if (!(arr1 instanceof Array) || !(arr2 instanceof Array)) return
根据上面 Molunerfinn 的回答,给我很有用的帮助,学到了!!!
解法1:不会出错
解法2:有缺陷,纯数字和字符串类型数字无法区分
我试了 可以啊
/* 第 59 题:给定两个数组,写一个方法来计算它们的交集。
例如:给定 nums1 = [1, 2, 2, 1],nums2 = [2, 2],返回 [2, 2]。 */
// 思路:遍历数组1,对每个元素判断其是否在数组2中,存在则提出来放到一个新数组里,并且从数组2中剔除,以确保下一次遍历不会出现重复的。
// 由于Array.splice()函数效率比较低,所以采用空间换取时间的方式,剔除的过程是将其他非交集元素放到新数组里。
// 想了想,还是用简单的splice吧。
你的a换成[1,1],b换成[1]再试试
是有问题。有受到调用数组长度影响。
不会受到长度影响
` /**
@info: 给定 nums1 = [1, 2, 2, 1],nums2 = [2, 2],返回 [2, 2]。
*/
var nums1 = [1,1];
var nums2 = [1];
function common(nums1,nums2) {
var resp = [];
nums1.forEach(ele => {
let idx = nums2.indexOf(ele);
if(idx > -1) {
resp.push(ele);
nums2.splice(idx, 1)
}
})
return resp
}
不错,个人感觉要是能在不改变原数组的基础上实现就更好了☺
你们上面都不对,这个才是正确的。
时间复杂度 O(n)
这是O(m,n)复杂度吧
emmm。。你这个也是n方的解法。你先是一层循环,里面用了indexOf和splice,然后indexof和splice都是O(n)
function intersect(m,n){
return new Set(m).size<=new Set(n).size?n.filter(x=>new Set(m).has(x)):m.filter(x=>new Set(n).has(x))
}
console.log(intersect([1, 2, 2, 1],[2, 2, 1]))
console.log(intersect([1,1],[1,2]))
测试用例
console.log(intersect([1,1],[1,2]))
输出应该是[1], 但你的是[1,1]你sort一下就已经是O(n lgn)了。。
Damn... 已修改
大佬们 我这样对不对
intersect(['1', 1, 2], ['1', '2']) // 输出 ['1', '2']
采用hash的话, 个人觉得不好区分数字1和字符串1,除非提前限定好数组值的类型。两个循环时间复杂度确实很差, 不过优点是可以区分数字和字符串。去重这一步估计还要额外增加复杂度
暴力一点吧。
[1,2,2,1],[2] 情况不成立
另一种方式
哈希表,时间复杂度O(m + n) m为nums1长度,n为nums2长度
这道题不是工程题,是道算法题。
求的是两个数组的最长公共子序列(子序列要求顺序,交集不需要)。所以上面用一个filter一个includes或者indexOf的都是错的。反例很简单。
或者
交集应该是[1]
跑一下你们的方法就能知道错了。
这道题两种思路,空间换时间,或者不用额外空间就提升时间复杂度。
空间换时间的思路是用个
Hash
表来存数组1的元素以及出现的个数(此处需要遍历n次,并存一个n级别的空间)。遍历数组2,发现数组2里有
Hash
表里的值就存到Result
数组里,并把Hash
表内该值次数减一(为0之后就Delete)。如果不存在Hash
表里,就跳过。这样时间复杂度就是(m+n)不用额外空间,就用遍历n的时候,判断值在不在m里,如果在,把m里的该值push到
Result
数组里,并将该值从m数组里删掉(用splice)。这样就是不用额外空间,但是提高了时间复杂度。返回所有符合结果的交集。
之前的错了,更新一下,感觉可以
解法有点问题,intersection([1,2,2,1],[2,1])