【解一】就。。第一眼就很直接很暴力,两层循环遍历两个数配一下,和等于target就return坐标。然后注意一下题目说不能用同一元素,再加上我内外两层找到的元素ab,再遍历到ba的时候其实已经判断过了,这没必要,所以直接规定内层循环的元素要在外层循环的后面就好了(一个右上三角形)。
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
for i in range(0,len(nums)):
for j in range(i+1,len(nums)):
if nums[i]+nums[j] == target:
return [i,j]
return []
【解二】两层循环即使有优化也显得时间复杂度有点高了,想做O(n)的怎么办呢?刚刚是试探着加嘛,那把加法变成减法不就有一个确定值了?我们可以先把这些数整成一个集合,就可以直接查询这个确定的值存不存在于数组里了,也就是说对第i个数,我们用target去减一下,就得到了它应该匹配的数,看这个数在不在。
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
s = set(nums)
for i in range(0,len(nums)):
num = target-nums[i]
if (num in s) and (nums.index(num) != i):
return[i,nums.index(num)]
return []
【解三】虽然看起来是O(n)了,但我们可以看到,有大集合的查询,还有index的查询,这些都蛮费时间的。但总体来说思路还是不错的,我们可以再抢救一下(啊呸!优化一下。跟解一一样,我们其实不需要双向的匹配,有一个上三角形就够了,所以我们查询的集合不需要一开始就整个大的,可以一路往后找一路把前面的元素更新进去,同时位置也不用index了,既然我们在更新集合,那顺手存一下位置呗。这里发现python真的好好用啊,可以直接写一个字典(曾经的C艹手残流下辛酸的泪水)。。。说具体点,维护一个字典随着遍历把看过的元素更新进去,数字本字作为字典的key,方便直接查询,数字的位置作为字典的value,方便找到后拿出来return结果。
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
sdict = {nums[0]:0}
for i in range(1,len(nums)):
num = target-nums[i]
if num in sdict:
return[sdict[num],i]
else: sdict[nums[i]] = i
return []