您的位置:首页 > 其它

【leetcode】1. 两数之和——寻找两数和为目标值得组合

2019-01-21 21:32 369 查看
版权声明:https://github.com/linshuang/full-stack https://blog.csdn.net/qq83833224/article/details/86584087

题目描述

给定一个整数数组 numsnumsnums 和一个目标值 targettargettarget,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。

输出示例:

给定nums=[2,7,11,15],target=9nums = [2, 7, 11, 15], target = 9nums=[2,7,11,15],target=9
因为 nums[0]+nums[1]=2+7=9nums[0] + nums[1] = 2 + 7 = 9nums[0]+nums[1]=2+7=9
所以返回 [0,1][0, 1][0,1]

思路1

非常自然能够想到的一种思路是:两个嵌套的forforfor循环。

  1. 第一个循环从000开始遍历numsnumsnums,记每次得到nums[i]nums[i]nums[i];
  2. 内嵌的第二个forforfor循环从i+1i+1i+1开始遍历numsnumsnums,记每次得到nums[j]nums[j]nums[j];
  3. 每一步判断nums[i]+nums[j]nums[i]+nums[j]nums[i]+nums[j]是否等于targettargettarget,等于则直接返回。

这种思路实现简单,但时间复杂度稍高为 o(n2)o(n^2)o(n2)。

代码

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——逼夹法

假如数组为有序的情况,分别将指针iii和jjj指向数组首位,那么我们可以通过当前和tmpSum=nums[i]+nums[j]tmpSum=nums[i]+nums[j]tmpSum=nums[i]+nums[j]与targettargettarget的关系进行有目的地移动iii和jjj:小于目标值,iii自增;大于目标值jjj自减。这便是逼夹法。
由于nums并不是有序的,那么需要先对数组进行一次 o(nlog⁡(n))o(n\log(n))o(nlog(n))的排序,再利用逼夹法,显而易见逼夹法的时间复杂度为o(n)o(n)o(n),所以整体复杂度也就是o(nlog⁡(n)+n)o(n\log(n)+n)o(nlog(n)+n)。

*注意:原题需要返回原数组下标,实际上只用逼夹是不合适的,因为得到的下标是排序后的数组下标,但该方法是能够获得相应的数值组合的。

代码

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

参考

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: