题目描述
给定一个整数数组
和一个目标值
,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
输出示例:
给定
因为
所以返回
思路1
非常自然能够想到的一种思路是:两个嵌套的 循环。
- 第一个循环从 开始遍历 ,记每次得到 ;
- 内嵌的第二个 循环从 开始遍历 ,记每次得到 ;
- 每一步判断 是否等于 ,等于则直接返回。
这种思路实现简单,但时间复杂度稍高为 。
代码
def twoSum(nums, target):
for i in range(len(nums)):
for j in range(i + 1, len(nums)):
sum = nums[i] + nums[j]
if sum == target:
return [i, j]
return []
思路2——逼夹法
假如数组为有序的情况,分别将指针
和
指向数组首位,那么我们可以通过当前和
与
的关系进行有目的地移动
和
:小于目标值,
自增;大于目标值
自减。这便是逼夹法。
由于nums并不是有序的,那么需要先对数组进行一次
的排序,再利用逼夹法,显而易见逼夹法的时间复杂度为
,所以整体复杂度也就是
。
*注意:原题需要返回原数组下标,实际上只用逼夹是不合适的,因为得到的下标是排序后的数组下标,但该方法是能够获得相应的数值组合的。
代码
def twoSum(self, nums, target):
nums.sort() # 从小到大排序
i = 0 # 头指针
j = len(nums) - 1 # 尾指针
result = []
while True: # 一直循环直至i>=j
sum = nums[i] + nums[j]
if sum == target: # 假如和便是目标
result.append([i, j]) # 记录结果
# 确定下一轮的指针
ii = i + 1
while ii < j and nums[ii] == nums[i] : # 跳掉重复的
ii += 1
i = ii
jj = j - 1
while jj > i and nums[jj] == nums[j]: # 跳掉重复的
jj -= 1
j = jj
elif sum > target: # 假如过大,j向前移动,即减少和
j -= 1
else: # 假如过小,i向后移动,即增加和
i += 1
if i >= j: # 逼夹跳出条件
break
return result
参考
- [1] leetcode原题
- [2] 详尽源码