350.两个数组的交集II

给定两个数组,编写一个函数来计算它们的交集。

示例 1:

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

示例 2:

输入: nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出: [4,9]

说明:

输出结果中每个元素出现的次数,应与元素在两个数组中出现的次数一致。
我们可以不考虑输出结果的顺序。

进阶:

如果给定的数组已经排好序呢?你将如何优化你的算法?
如果 nums1 的大小比 nums2 小很多,哪种方法更优?
如果 nums2 的元素存储在磁盘上,磁盘内存是有限的,并且你不能一次加载所有的元素到内存中,你该怎么办?

方法一 利用Map

这个利用Map原因是,数组里面可能有重复元素,但是Set结构里面是不能有重复的元素。
新建一个res来保存两个数组重叠的交集,在主函数中首先判断下谁的数组长度比较短,短的那一个为Map对象的复制体(如果两个数组的元素数目相差很多的话,优势就会体现出来,额外的空间就很少很多。你懂得!)
Map复制完以后,接下来的for循环就是遍历另一个数组.与map中的元素进行比较,相同的话,把元素从map中删除,同时把该元素放入我们的res数组中。在对map相减的时候,对map的长度进行判断,如果为0,就提前结束循环(刚好他们重复的元素都在数组的前半部分呢?这样后面就可以不再遍历了,特殊情况下还是可以减少时间的)
  var intersect = function(nums1, nums2) {
    let res = [];
    let map = {};
    if (nums1.length < nums2.length) {
        for (let e of nums1) {
            map[e] = map[e] + 1 || 1;

        }
        for (let e of nums2) {
            if (map[e]) {
                res.push(e);
                map[e]--;
                if(map.size==0)
                {break;}
            }
        }
    } else {
        for (let e of nums2) {
            map[e] = map[e] + 1 || 1;

        }
        for (let e of nums1) {
            if (map[e]) {
                res.push(e);
                map[e]--;
                 if(map.size==0)
                {break;}
            }
        }
    }

    return res;
};

方法二 对两者进行排序,双指针移动法

牵扯事先排序,那么该算法肯定不是最优先解,谁知道排序会占用多少时间呢?这里我们就把方法归结于暴力破解吧,虽然代码投机取巧,但是复杂度不小
思路:排完序以后两个数组内的元素都是从小到大排列的,这时候用两个指针i,j来遍历数组。这里的i,j是指数组的索引,当数组中的两个都相同的,把该元素加入arr数组,然后两个指针都相加。相反,谁的值小,谁的指针移动(这就是为什我们要排序的目的)
var intersect = function(nums1, nums2) {
    nums1.sort((x, y) => x - y)
    nums2.sort((x, y) => x - y)
    let i = 0,
        j = 0;
    let arr = []
    while (i < nums1.length && j < nums2.length) {
        if (nums1[i] == nums2[j]) {
            arr.push(nums1[i]);
            i++;
            j++
        } else if (nums1[i] > nums2[j]) { j++ } else { i++ }

    }
    return arr
    };
方法三 暴力破解(这个是真正的暴力破解)
两个for循环解决,时间复杂度是真的高。面试遇到,你给面试官说个这个方法(并且你就知道这一种)嘿嘿,那么你的博客就会多上一篇凉凉面经!
下面的代码没有测试,思路就是那样,不建议大家掌握这种,只会暴力,那还学算法干嘛

var intersect = function(nums1, nums2) {

    let map = new Map()
    let arr = []
    for (let i = 0; i < nums1.length; i++) {
        for (let j = 0; j < nums2.length; j++) {
            if (nums2[j] == nums1[i]) {
                arr.push(nums1[i])
                map.delete(nums1[i])
                map.set(nums1[i])
                break; //退出本次循环,找到重复的,后面再出现重复的,我也不会添加
            }
        }
    }
    return arr
}

你可能感兴趣的:(LeetCode算法JS实现)