题目
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/two-sum
示例
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
求解
第一种求解思路:用target减去nums中的元素值,判断差值是否在nums列表中。这种方法需要建立两重循环:一重遍历nums中所有元素;一重遍历第一次循环所取元素之后的剩余元素。即如果列表长度为N,第一次循环取到n时,第二次循环需要取遍 ( N − n + 1 ) , ( N − n + 2 ) , ⋅ ⋅ ⋅ , ( N − 1 ) (N-n+1),(N-n+2),···,(N-1) (N−n+1),(N−n+2),⋅⋅⋅,(N−1)。此时的时间复杂度为 O ( n 2 ) O(n^2) O(n2)。
class Solution:
def twoSum(self, nums: list, target: int) -> list:
lenght = len(nums)
for i in range(lenght):
print(i)
result = target - nums[i]
for j in range(i+1,lenght): #i+1:剔除当前元素,从下一个元素开始遍历
print(j)
if result == nums[j]:
break
if result == nums[j]:
break
return [i,j]
if __name__=="__main__":
s = Solution()
nums=input("input a list\n")
target = input("input a target\n")
nums = eval(nums)
target = int(target)
e = s.twoSum(nums, target)
print(e)
第一次刷LeetCode,不知道怎么提交代码,试了几次才知道不用提交主函数,只把类和函数的定义部分提交就可以了。提交后代码通过了,但是用时太长,毕竟这就是个暴力求解。于是查看别人写的耗时很少的方法。
第二种求解思路:采用字典。遍历nums列表时,判断当前元素是否存在于字典之中,如果不存在,将target与列表元素的差值存入字典,字典的键为差值,字典的值为nums当前元素的索引值;如果存在则返回当前元素对应字典的值和当前元素在列表中的索引值。这种思路其实也是两次遍历,但是字典的遍历时间复杂度为 O ( 1 ) O(1) O(1),这是由字典底层结构决定的,因此这种方法的时间复杂度为 O ( n ) O(n) O(n)。
class Solution:
def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
n = len(nums)
d = {} #创建一个空字典
for x in range(n):
a = target - nums[x] # a为差值 也是字典的key
if nums[x] in d: # 如果字典中存在num[x]则返回字典的值
return d[nums[x]],x
else:
d[a] = x # 如果不存在则保存为一个新的键