题目链接:leetcode,两数之和
对于这道题目来讲,题目要求从一个列表中寻找到两个合适的值,相加后等于目标值。
首先能想到的便是利用双循环嵌套遍历整个列表,找到相加等于目标值的两个合适的值,并返回其索引,代码实现如下:
class Solution:
def twoSum(self, nums, target):
for i in range(len(nums)):
for j in range(len(nums)):
if nums[i]+nums[j] == target and i != j:
return [i, j]
但是这样不够炫酷,让我们想想,题目要求达成的目标是这样的:
x
1
+
x
2
=
t
a
r
g
e
t
(
x
1
,
x
2
∈
n
u
m
s
)
x_1+x_2=target(x_1,x_2\in nums)
x1+x2=target(x1,x2∈nums)
那么,将公式改写一下,则变成了:
t
a
r
g
e
t
−
x
1
=
x
2
(
x
1
,
x
2
∈
n
u
m
s
)
target-x_1=x_2(x_1,x_2\in nums)
target−x1=x2(x1,x2∈nums)
这样的话我们就可以在列表中寻找差值就好了,代码如下:
class Solution:
def twoSum(self, nums, target):
for i in range(len(nums)):
if target-nums[i] in nums:
for j in range(i+1, len(nums)):
if nums[j] == (target-nums[i]):
return [i, j]
可是这样还是不够炫酷,因为还是使用了两个循环,效率较低。
再让我们回想一下上一段代码所要完成的目标,其实在求到差值后,我们仅仅需要在列表里找到对应差值的索引返回就好了,这种情况当然是使用字典啦~仅需使用以下函数即可将列表转换为字典啦:
for index, num in enumerate(nums):
可是字典也存在着问题,即无法从value值找到相对应的key值(字典的结构为{key : value}),还是无法达成目的。但是这个问题很好解决,只要我们再利用一个循环将key值和value值倒过来存放就行了。之后我们再去查找相对应的差值索引就非常方便了,代码如下:
class Solution:
def twoSum(self, nums, target):
hashmap = {} #建立空字典
for index, num in enumerate(nums):
hashmap[num] = index #将key值和value值倒过来存放
for i in range(len(nums)):
if (target-nums[i]) in nums and i != hashmap[target-nums[i]]:
return [i, hashmap[target-nums[i]]]
如果不看我们构造字典的过程,仅搜索差值索引的步骤只使用了一个循环,还是相较于第一种方式有进步的,但是总体上还是使用了两个循环,效率仍没有明显的进步。
其实到现在你应该发现了,按照这个思路,我们可以使用字典来寻找差值的索引不就好了吗。但是单纯的使用一个循环去颠倒key值和value值太浪费了,我们可以将搜索索引的步骤也放在这个循环里完成,那么代码如下:
class Solution:
def twoSum(self, nums, target):
hashmap = {} #建立空字典
for index, num in enumerate(nums):
if (target-num) not in hashmap:
hashmap[num] = index #颠倒存放
else:
return [index, hashmap[target-num]]
上面的代码可以理解为“如果我在字典中找不到差值,就将自己放入到字典中,看看自己能不能成为后一个/几个数字的差值”。
当循环数下降后,程序运行时间从最初的1100毫秒左右降至64毫秒,效果显著。
若有更好的解决思路欢迎在评论区留言补充~
爱你们~