Swift && LeetCode 第一题:两数之和

454 阅读1分钟

Offer 驾到,掘友接招!我正在参与2022春招系列活动-刷题打卡任务,点击查看活动详情

平时不能坚持刷算法题,一来,是因为工作本身有时候也会忙,所以会变懒惰,二来,因为算法题确实有时候很烧脑,没有领悟的话,做起来会怀疑人生。但是贵在坚持,也希望大家共勉。

今天我们从第一题开始:两数之和

两数之和

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target  的那 两个 整数,并返回它们的数组下标。

暴力解法 (穷举)

这种类型的问题,最简单的解法当属暴力的穷举了。双层循环,然后相加、判断,并返回数组下标就可以了。

class Solution {
    func twoSum(_ nums: [Int], _ target: Int) -> [Int] {
        var otherNum = [Int]() 
        for i in 0..<nums.count {
            for j in i+1..<nums.count {
                if nums[i]+nums[j] == target {
                    otherNum.append(i)
                    otherNum.append(j)
                    return otherNum 
                }
            }
        } 
        return otherNum 
    }
}

这种解法:简单粗暴,所以时间复杂度 O(N^2) 较高,空间复杂度 O(1) 还好。

但是,我想这一定不是我们想要的!我们通过LeetCode最终的执行就知道,在面对更多的数据时,效率偏低。那么使用数组的循环就一定不是我们想要的最种解法。

我们知道哈希表来处理此类问题应该更快。原因就是:哈希表在查询上是通过映射来查找,比数组遍历更快。所以我们改改实现方案,尽量往哈希表上靠。

截屏2022-03-03 下午10.37.46.png

哈希表解法

将数组转成一个键值对,使用数组中的value做为键值对的key,数组中的index作为键值对的value,然后在通过做减法在键值对中查询。

class Solution { 
    func twoSum(_ nums: [Int], _ target: Int) -> [Int] { 
        var otherNum = [Int]() 
        var numsDict = Dictionary<Int, Int>() 
        for i in 0..<nums.count { 
            let num = nums[i] 
            let nextNum = target - num 
            if numsDict.keys.contains(nextNum) { 
                otherNum.append(numsDict[nextNum]!) 
                otherNum.append(i) break 
            } 
            numsDict.updateValue(i, forKey: num) 
        } 
        return otherNum 
    } 
}

哈希表的查询时间为 O(1),这种解法:时间复杂度降低到 O(N),但空间复杂度也是 O(N)。

截屏2022-03-03 下午11.16.28.png

这种方案执行效率上比穷举还是有优势的,同时我看可以看出,其实哈希表在这种这种场景下效率还是比较高的。

当然,也还有其他的解法,比如说先排序,然后在使用双指针的解法。双指针在解决有序数组上也是一个不过的解法。不过这题,我觉得考察的更多应该还是使用哈希表,哈哈!今天就写到这里。