一、题目
给你三个整数数组 nums1、nums2 和 nums3 ,请你构造并返回一个 元素各不相同的 数组,且由 至少 在 两个 数组中出现的所有值组成。数组中的元素可以按 任意 顺序排列。
二、思路
解题思路:
- 先把三个数组都变成 hashmap
- 循环数组,发现元素在另两个 hashmap 里面出现过就丢进去数组
- 最后输出前利用 Set 去重
三、代码
var twoOutOfThree = function (nums1, nums2, nums3) {
const map1 = nums1.reduce((l, i) => l[i] = true && l, {})
const map2 = nums2.reduce((l, i) => l[i] = true && l, {})
const map3 = nums3.reduce((l, i) => l[i] = true && l, {})
const set = new Set()
single(nums1, map2, map3, set)
single(nums2, map1, map3, set)
return [...set]
};
function single (arr, map1, map2, set) {
arr.forEach(item => {
if (map1[item] || map2[item]) {
set.add(item)
}
})
}
结果:
四、涉及
这里解题的思路是用到了 hashmap 的思路。
1、什么是 hashmap
HashMap底层就是一个数组结构,数组中的每一项又是一个链表。数组+链表结构,新建一个HashMap的时候,就会初始化一个数组。Entry就是数组中的元素,每个Entry其实就是一个key-value的键值对,它持有一个指向下一个元素的引用,这就构成了链表,HashMap底层将key-value当成一个整体来处理,这个整体就是一个Entry对象。HashMap底层采用一个Entry【】数组来保存所有的key-value键值对,当需要存储一个Entry对象时,会根据hash算法来决定在其数组中的位置,在根据equals方法决定其在该数组位置上的链表中的存储位置;当需要取出一个Entry对象时,也会根据hash算法找到其在数组中的存储位置, 在根据equals方法从该位置上的链表中取出Entry;
2、为什么要用 hashmap
数组与 hashmap 的对比
- 数组:其实所谓的数组指的就是一组相关类型的变量集合,并且这些变量彼此之间没有任何的关联。存储区间连续,占用内存严重,数组有下标,查询数据快,但是增删比较慢;
- 链表:一种常见的基础数据结构,是一种线性表,但是不会按照线性的顺序存储数据,而是每一个节点里存到下一个节点的指针。存储区间离散,占用内存比较宽松,使用链表查询比较慢,但是增删比较快;
3、怎么用 hashmap
es6 提供了 map 的用法,详情可以去查看我的文章 js 学习之路 —— Map ,或者也可以看 官方 es6 文档
还有一种就是自己手写,就好比上面代码里一样
const map1 = arr.reduce((l, i) => l[i] = true && l, {})
五、其他想法
1、去重再组合比较
解题思路:
- 先将各个数组去重
- 把所有组合组合在一起
- 用 .filter() 进行比较,如果数组有相同的则提取出来。
var twoOutOfThree = function (nums1, nums2, nums3) {
const newNums1 = new Set(nums1)
const newNums2 = new Set(nums2)
const newNums3 = new Set(nums3)
const numsArray = [...newNums1, ...newNums2, ...newNums3]
const resArray = numsArray.filter((num, index) => numsArray.indexOf(num, index + 1) > -1)
return [...new Set(resArray)]
};
结果: