version 1:
使用暴力的方法,两层循环遍历所有的元素,查找加和为目标target的元素对,并返回元素的下标索引,该方法的时间复杂度为,代码和结果展示如下:
class Solution:
def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
"""
use the idea of select sort
to traverse the list
to find two numbers which sum is target
"""
for i in range(0, len(nums)):
# from zero to the length of list
for j in range(i+1,len(nums)):
if nums[i]+nums[j] == target:
return[i,j]
# if not found, return null
return []
version 2:
改进第一个版本的暴力方法,只用一遍循环,第二层利用列表的index()函数,对每个当前的元素,在后续的元素中查找,是否存在target-nums[i]的元素。若有,则返回下标;没有,则继续。这个方法的时间复杂度为。代码与结果如下,可以看出时间的巨大改进:
class Solution:
def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
"""
based on the version 1
just traverse in one loop
use index() function to find target - nums[i] in the list[i+1:]
"""
for i in range(0, len(nums)):
# from zero to the length of list
if (target - nums[i]) in nums[i+1:]:
# find target - nums[i] in the list[i+1:]
# if exist then return
# else continue
j = nums.index(target-nums[i],i+1)
return [i,j]
# if not found, return null
return []
version 3:
前面两个版本均处于对列表的操作,即在没有改动数据结构的层面提高算法。进一步的提升可以尝试使用更加高效且适合问题的数据结构,巧妙使用字典可以达到目的。
为求通过一次遍历找到答案,将列表结构改用字典结构表示,对于每个元素,在字典中的key为配对元素的数值,即target-nums[i],value则为索引。可以通过扑克进行形象理解,一次遍历代表你一张张的抓牌,在抓到新牌的时候看一眼自己手上的牌(字典),是否与当前牌配对的,即key为配对的。若有则出牌,若没有则将牌加入。本次算法时间复杂度为,为真正的
,空间复杂度也是很
,前面的空间复杂度全是
。version 2其实还有列表index()方法的时间复杂度,只是我们将其处理为常数复杂度了,某种程度上不算是完全意义上的
时间复杂度。代码与结果如下:
class Solution:
def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
"""
build a dictionary to store the element you hold
for each element you hold now to find target - nums[i] in dictionay
if found then return
else add element to the dictionary
"""
dictionary = {}
for i in range(0, len(nums)):
# if target - nums[i] exist in the dictionary then return
if nums[i] in dictionary:
return [dictionary[nums[i]],i]
# else add the element to the dictionary
else:
dictionary[target-nums[i]]=i
# if not found, return null
return []
至此,本题完成,作为刷leetcode的开端,希望自己能坚持,并有所收获。
本题python版本的提升至此,若想进一步提升,笔者暂束手无策,也许改用C++能有更大效率的提高。