题目:给定一个整数数组和一个目标值,找出数组中和为目标值的两个数。你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用。
示例:
给定nums=[2,7,11,15],target=9
因为num[0]+num[1]=2+7=9
所以返回[0,1]
解题思路:
1、看到这道题首先想到的解法就是,先固定一个值num,再遍历寻找 target-num,这种算法的时间复杂度是O(n^2),空间复杂度是O(1);
2、每次判断target-num[i]对应的值是否在num[i+1:]中。但这里我们要注意一个问题,如果列表中有相同的元素,例如[3,3],我们对应的target=6,这个时候我们适用list.index的时候要注意index返回得第一个值的位置,我们应该使用list[i+1].index+i+1.这种算法的时间复杂度是O(n),比第一种算法快,但是如果我们每次查找的都是最差的情况,那么我们花费O(n)的时间复杂度,并且索引的时候我们使用了index函数和切片操作,这些都非常消耗时间。
3、我们每次从num[:i]中去查找是否有target-nums[i]。这种做法就避免了上述问题中的查找最差的情况(num_c是空列表开始)
代码如下:
1 class Solution: 2 def twoSum(self, nums, target): 3 """ 4 :type nums: List[int] 5 :type target: int 6 :rtype: List[int] 7 """ 8 #创建一个空字典 9 nums_hash={} 10 #用len()方法取得nums列表的长度 11 num_len=len(nums) 12 for i in range(num_len): 13 dif=target-nums[i] 14 #检查dif是否在字典中 15 if dif in nums_hash: 16 #在的话,返回该值对应原序列中的位置,和当前元素的在原序列中的位置(索引) 17 print(nums_hash[dif],i) 18 return [nums_hash[dif],i] 19 #如果不在,将当前值作为键,将其值作为值存入这个空字典中 20 nums_hash[nums[i]]=i 21 return []
作为渣渣的我,为了自己测试代码的准确性,又写了如下测试用例
nums=[2,7,11,15] target=9 #类函数的调用方式 类名+.+函数名 Solution.twoSum(1,nums,target)
拓展:如果让打印出所有能够构成给定值的组合:
示例nums=[3,3,3,2,3]
target=6
返回(0,1)、(1、2)、(2、4)
代码如下:
1 class Solution: 2 def twoSum(self, nums, target): 3 """ 4 :type nums: List[int] 5 :type target: int 6 :rtype: List[int] 7 """ 8 #创建一个空字典 9 nums_hash={} 10 #用len()方法取得nums列表的长度 11 num_len=len(nums) 12 for i in range(num_len): 13 dif=target-nums[i] 14 #检查dif是否在字典中 15 if dif in nums_hash: 16 #在的话,返回该值对应原序列中的位置,和当前元素的在原序列中的位置(索引) 17 print(nums_hash[dif],i) 18 # return [nums_hash[dif],i] 19 #如果不在,将当前值作为键,将其值作为值存入这个空字典中 20 nums_hash[nums[i]]=i 21 return [] 22 23 #测试模块 24 # nums=[2,7,11,15] 25 # target=9 26 # #类函数的调用方式 类名+.+函数名 27 # Solution.twoSum(1,nums,target) 28 29 a=[3,3,3,2,3] 30 b=6 31 #类函数的调用方式 类名+.+函数名 32 Solution.twoSum(1,a,b)