代码随想录二刷-哈希表-两个数组的交集(JS)

349.两个数组的交集

题目

给定两个数组 nums1 和 nums2 ,返回 它们的交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。

示例 1:

输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2]
示例 2:

输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出:[9,4]
解释:[4,9] 也是可通过的

提示:

1 <= nums1.length, nums2.length <= 1000
0 <= nums1[i], nums2[i] <= 1000

方法

抓住本题特性不能有重复元素,所以我们选择Set数据结构

将其中一个数组全都加入Set中

(也可以直接创建包含该数组的set)

然后遍历另一个数组,如果set中含有该数组的元素,就将该元素加入到一个新的reset中

最后将reset转化为数组

代码

/**
 * @param {number[]} nums1
 * @param {number[]} nums2
 * @return {number[]}
 */
var intersection = function(nums1, nums2) {
    let set = new Set();
    let reSet = new Set();
    // 1.可以直接创建时加入
    // let set = new Set(nums1);
    // 2.循环比迭代器快
    for (let num of nums1){
        set.add(num);
    }
    for (let num of nums2){
        if (set.has(num)){
            reSet.add(num);
        }
    }
    return Array.from(reSet);
};

350.两个数组的交集 II

题目

给定两个数组 nums1 和 nums2 ,返回 它们的交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。

示例 1:

输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2]
示例 2:

输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出:[9,4]
解释:[4,9] 也是可通过的

提示:

1 <= nums1.length, nums2.length <= 1000
0 <= nums1[i], nums2[i] <= 1000

方法

1.使用Map解决

我的方法:

先将nums1和nums2分别存入Map中,然后遍历nums1Map,如果nums1Map中的key在num2Map中存在,取两者的最小value,加入最小value次这个key

【我的方法绕了一些圈子】

别人的方法:

还可以使用map来解决,具体操作如下

遍历nums1中的所有元素,把它存放到map中,其中key就是nums1中的元素,value就是这个元素在数组nums1中出现的次数。

遍历nums2中的所有元素,查看map中是否包含nums2的元素,如果包含,就把当前值加入到数组中,然后对应的value要减1。

作者:sdwwld

【我的思路的简化】

2.双指针解决

先对两个数组进行排序,然后使用两个指针,分别指向两个数组开始的位置。

如果两个指针指向的值相同,说明这个值是他们的交集,就把这个值加入到数组中,然后两个指针在分别往后移一步。
如果两个指针指向的值不同,那么指向的值相对小的往后移一步,相对大的先不动,然后再比较
一直重复上面的操作,直到其中一个指针不能再移动为止。

作者:sdwwld

代码

我的方法

/**
 * @param {number[]} nums1
 * @param {number[]} nums2
 * @return {number[]}
 */
var intersect = function(nums1, nums2) {
    let nums1Map = new Map();
    let nums2Map = new Map();
    let res = new Array();
    for (let i = 0;i < nums1.length;i++){
        nums1Map.set(nums1[i],(nums1Map.get(nums1[i]) || 0) + 1);
    }
    for (let i = 0;i < nums2.length;i++){
        nums2Map.set(nums2[i],(nums2Map.get(nums2[i]) || 0) + 1);
    }
    for (let x of nums1Map) {
        if (nums2Map.has(x[0])){
            let count = Math.min(x[1],nums2Map.get(x[0]));
            while (count--) {
                res.push(x[0]);
            }
        }
    }
    return res;
};

别人的Map方法

/**
 * @param {number[]} nums1
 * @param {number[]} nums2
 * @return {number[]}
 */
var intersect = function(nums1, nums2) {
    let nums1Map = new Map();
    let res = new Array();
    for (let i = 0;i < nums1.length;i++){
        nums1Map.set(nums1[i],(nums1Map.get(nums1[i]) || 0) + 1);
    }
    for (let i = 0;i < nums2.length;i++){
        if (nums1Map.get(nums2[i]) > 0){
            res.push(nums2[i]);
            nums1Map.set(nums2[i],nums1Map.get(nums2[i]) - 1);
        }
    }
    return res;
};

其实和用数组存储字母差不多,都是遇到相同的字符 value–

双指针方法

/**
 * @param {number[]} nums1
 * @param {number[]} nums2
 * @return {number[]}
 */
var intersect = function(nums1, nums2) {
    let res = new Array();
    // 划重点!!!!
    //sort()根据ASCII码进行的比较
    // 如果不传入函数的话,只有个位数的比较是正确的
    nums1.sort((a,b) => a - b);
    nums2.sort((a,b) => a - b);
    let one = two = 0;
    while (one < nums1.length && two < nums2.length){
        if (nums1[one] == nums2[two]){
            res.push(nums1[one]);
            one++;
            two++;
        } else if (nums1[one] > nums2[two]) {
            two++;
        } else {
            one++;
        }
    }
    return res;
};

你可能感兴趣的:(散列表,数据结构,算法)