算法 Notes |LeetCode 349. 两个数组的交集 - easy

1,811 阅读4分钟

对于算法而言,陌生而神秘,却是成长经历中必经之路。

曾经无数次各种找资料,寻求各种所谓的七天搞定算法秘籍,可结果都是无终而返。

其实换句话来讲,我也是搞 Android 的,有时候看到所谓 7 天让你成为 Android 大牛,也是不屑一顾的。没有长远的积累,哪儿来的大牛?曾经折腾很久的东西,如今 easy 一批,说白了,还是时间久了,写的多了。

一个人,难免会走进各种误区。经历了职场 PUA,顿悟过来,别无他求,自我积累为上。

还是鸡老大的那句话:

  • Just do it now.

送给屏幕前的你我,共勉。

针对算法,将采取暴力 Study 法,勤能补拙!多学多练。

个人是个算法白痴,尽量完善每一步,不足之处,欢迎吊打~

欢迎各位大佬吊打~

附上 GitHub 地址:

349. 两个数组的交集

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

示例 1:

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

示例 2:

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

  说明:

  • 输出结果中的每个元素一定是唯一的。
  • 我们可以不考虑输出结果的顺序。

交集概念回顾

以上图为例,A、B 之间重合部分为交集 C。

例如,现有 A、B 如下:

  • A:1 3 4 5 6
  • B:2 3 3 4

重合部分的内容为:

  • 3 4

可得出交集 C 等于 3 4。

交集的概念,用大白话的方式就是,你有我也有,这是交集。此处衍生并集则是,你的加我的,去掉重复的,就是并集。

解题思路 一、Set + contains

大概思路如下:

  • 对于输入型数据基本校验,这里不过多解释;
  • 通过 Set 唯一特性,过滤第一个数组;
  • 将第一个过滤好的数组和第二个数组进行对比,包含,则代表重合,添加 Result 中;
  • 遍历 Reslut,赋值 return array

代码如下:

class Solution {
    fun intersection(nums1: IntArray, nums2: IntArray): IntArray {
        if(nums1.isEmpty() || nums2.isEmpty()){
            return IntArray(0)
        }
        var tempSet = hashSetOf<Int>()
        var resultSet = hashSetOf<Int>()
        for(num1 in nums1){
            tempSet.add(num1)
        }
        for (num2 in nums2){
            if(tempSet.contains(num2)){
                resultSet.add(num2)
            }
        }
        var resultIntArray = IntArray(resultSet.size)
        var index = 0
        for(resultNum in resultSet){
            resultIntArray[index++] = resultNum
        }
        return resultIntArray
    }
}

消耗情况:

解题思路 二、Kotlin intersect()

class Solution {
    fun intersection(nums1: IntArray, nums2: IntArray): IntArray {
        if(nums1.isEmpty() || nums2.isEmpty()){
            return IntArray(0)
        }
        return nums1.intersect(nums2.asList()).toIntArray()
    }
}

消耗情况:

相比原始的第一种方案,执行用时以及内存消耗均增加不少,对比代码后,此方式增加了两次转 List 操作。

解题思路 三、继续优化第二条

上面说到,由于多次转 List,造成了一定的消耗,那么接下来,我少创建下,顺便简化下代码呢?

class Solution {
    fun intersection(nums1: IntArray, nums2: IntArray): IntArray {
        if(nums1.isEmpty() || nums2.isEmpty()){
            return IntArray(0)
        }
        return nums1.intersect(nums2.asList()).toIntArray()
    }
}

消耗情况:

有点尴尬咯。

解题思路 四、学习下排序 + 双指针

参考题解:

先附上代码部分:

class Solution {
    fun intersection(nums1: IntArray, nums2: IntArray): IntArray {
        if(nums1.isEmpty() || nums2.isEmpty()){
            return IntArray(0)
        }
        var i = 0
        var j = 0
        var index = 0
        var resultSet = hashSetOf<Int>()
        // 排序的目的是为了下面双指针移动时数据有迹可循,有规律可循
        nums1.sort()
        nums2.sort()
        // 双指针范围不得超出输入数组长度
        while (i < nums1.size && j < nums2.size){
        	// 关键是这块逻辑判断,各位认真画图,很容易理解了
            if(nums1[i] == nums2[j]){ 
                resultSet.add(nums1[i])
                i++
                j++
            }else if(nums1[i] < nums2[j]){
                i++
            }else if(nums1[i] > nums2[j]){
                j++
            }
        }
        var resultArray = IntArray(resultSet.size)
        for (resultNum in resultSet){
            resultArray[index++] = resultNum
        }
        return resultArray
    }
}

消耗程度:

End

单纯的从上图结果来看,还是第一次通过 Set + contains 效率最高。关于双指针这块,虽然是画了很长时间图,赶紧还是理解差点意思。

似乎隐隐约约感受到了算法的重要性,换句话而言的话,也就是算法的思想吧。

不过整体蛮开心的,好歹也算是人生意义上首次搞定啦~

欢迎大佬吊打~

路漫漫其修远兮,吾将上下而求索。

参考资料