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最终的执行就知道,在面对更多的数据时,效率偏低。那么使用数组的循环就一定不是我们想要的最种解法。
我们知道哈希表来处理此类问题应该更快。原因就是:哈希表在查询上是通过映射来查找,比数组遍历更快。所以我们改改实现方案,尽量往哈希表上靠。
哈希表解法
将数组转成一个键值对,使用数组中的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)。
这种方案执行效率上比穷举还是有优势的,同时我看可以看出,其实哈希表在这种这种场景下效率还是比较高的。
当然,也还有其他的解法,比如说先排序,然后在使用双指针的解法。双指针在解决有序数组上也是一个不过的解法。不过这题,我觉得考察的更多应该还是使用哈希表,哈哈!今天就写到这里。