大家好,我是基山督。其实我并不是计算机专业的,以往会一点C基础语言,在浙大的PTA上做了不少题目。无意间发现Leetcode,真的是大神云集。我对算法还是比较感兴趣的,因为非科班出身说来惭愧只有Matlab用的熟练一些。之前自学了一下Python,看完了《Python编程——从入门到实践》那本书,跟着也写了不少代码。苦于没有习题良久,等我发现Leetcode的时候已经快忘得差不多了。准备之后重新捡起来,争取每天更新一个算法题的专栏,最久不超过两天。如果哪天我超出限时了,请疯狂@我,喷我。不知道还有没有小伙伴一起打卡呀?计划从简单题入手,今天是两数之和。应该算个纯小白,比较菜别见怪,欢迎讨论分享。
题目重现:题目
刚看到这道题的时候我第一想法就是用两个for循环遍历。
于是我的第一次代码提交如下:
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
m = len(nums)
for i in range(m):
for j in range(i+1,m):
if nums[i]+nums[j] == target:
return [i,j]
return []
执行用时:6040 ms
内存消耗:14.5 MB
range函数左闭右开,需要注意索引从0开始。
后面看评论区受到启发说:其实只需要一次for循环,第二次判断target-nums[i]是否在nums里面就可以,改进如下:
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
m = len(nums)
for i in range(m):
if target-nums[i] in nums and i != nums.index(target-nums[i]):
return [i,nums.index(target-nums[i])]
break
return []
执行用时:1200 ms
内存消耗:14.5 MB
里面index函数返回元素从零开始的索引。
这之后的代码基本就是来自评论区的大神了:
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
m = len(nums)
for i in range(1,m):
temp = nums[:i]
if (target - nums[i]) in temp:
j = temp.index(target - nums[i])
return [j,i]
执行用时:452 ms
内存消耗:14.6 MB
这个真的是聪明,因为只需要搜索i前面或者后面的区间,所以可以先进行切片,并且从1开始。最后return的时候也是j在前。
class Solution(object):
def twoSum(self, nums, target):
num_dict = {}
for i, num in enumerate(nums):
num_dict[num] = i
for i, num in enumerate(nums):
j = num_dict.get(target - num)
if j is not None and i!=j:
return [i, j]
执行用时:60 ms
内存消耗:15.7 MB
使用字典大大加快了运行速度,enumerate函数可以将对应的值和索引同时取出。第一次循环后字典里面没有重复的数据。第二个for循环得到target-num的索引值。需要注意的是i!=j 这条件不能少,因为有【3,2,4】,tagert=6就会返回两个0
最后是哈希表,以前没听说过,比较难理解。
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
hashmap = {}
for index, num in enumerate(nums):
another_num = target - num
if another_num in hashmap:
return(hashmap[another_num], index)
break
hashmap[num] = index
类似上面字典的用法,只不过上文是先创造好字典再寻找,它是一边寻找一边创造字典。
刚开始的时候真的挺心累的,感觉自己就是被各路大神按在地上摩擦。不过思考做题也蛮有趣的,欢迎大家一起打卡~~坚持就是胜利✌