题目
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。
示例:
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/two-sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
普通做法
题目中的数组在python3中的表示为列表,解题直观上围绕列表的相关方法运用展开,遍历数组列表,判断 nums[i] 与索引值 i 之后的值之和是否等于target(或者得到每次 target 与 nums[i] 的差值,判断是否存在索引值 i 之后的值与差值相等)。
数组中同一个元素不能使用两遍: 返回的数组下标不能相同
注:
完整代码在数据预处理时需要把从键盘输入的字符串类型转换为列表类型
代码
//两层循环
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
for i in range(len(nums) - 1):
for j in range(i + 1,len(nums)):
if nums[i] + nums[j] == target:
return [i,j]
// 一次遍历 + 检索
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
for i in range(len(nums) - 1):
//得到差值
j = target - nums[i]
if j in nums[i + 1:]:
//数组中同一个元素不能使用两遍
z = nums.index(j,i + 1)
//注:str.index(object)方法是返回数组中特定对象出现的第一次的位置
return [i,z]
- 结果相同↓
超出时间限制
测试示例没有全部通过
优化改进
查找差值的过程决定了运行效率,采用哈希表(散列表),理想情况下时间复杂度为O(1)
- Hash(key) = Addr
// 哈希表,字典数据类型
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
Hash = {}
for i in range(len(nums)):
Hash[nums[i]] = i
for i in range(len(nums)):
j = Hash.get(target - nums[i], 0)
if j != i and j > i and j is not None:
return [i,j]
发现也可以写进一次遍历
// 运行时间和内存差别很小
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
hash={}
for i in range(len(nums)):
//返回匹配值的位置
j = hash.get(target-nums[i])
if j is not None :
return [j,i]
hash[nums[i]]=i
问题解决
出现KeyError
有符合条件的不存在的键,如nums[]数组列表中存在一个与target相等的值,限定哈希表值不为空;
TypeError: get() takes no keyword arguments
j = Hash.get(target - nums[i], default=None)
把默认值 default=None 改成具体值 0
- 返回的结果重复
如[0,1]和[1,0]是同一组值,加入哈希表值的限定,如大于已知下标值或小于已知下标值,然后return;
key冲突
一次遍历时,先判断再添加哈希表
总结
- 学到重复值的检索方法
① list.index(object)
list.index(x) : 得到第一次匹配 x 值的位置
list.index(x, i + 1) :得到索引位置 i 之后的序列中第一次匹配 x 值的位置
② enumerate(list)
输出类型是元组
能够得到[(对应位置,列表元素),…]的集合,某值重复时利用循环遍历能够得到所有位置 - 哈希表查找
dict.get(value,default = None)
dict[key] = value