两数之和
> 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
>
> 你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
>
> 示例:
>
> 给定 nums = [2, 7, 11, 15], target = 9
>
> 因为 nums[0] + nums[1] = 2 + 7 = 9
> 所以返回 [0, 1]
思路:
1、使用暴力搜索法,两层循环。
2、采用hash表,用空间换时间,减少循环次数,遍历a,得到匹配表[b=target-a],与a匹配。
举例:
hash=[],target=7,a=2,假设列表中存在5,那么就说存在一个匹配,但是此时列表中为空,找不到与之匹配的元素,就将2添加到hash中,此时hash=[2],当a=5时,b=2,由于hash中已经存在2,说明2与5正好达成一个匹配,由于题目说明只存在一个答案,否则我们还要将2弹出去,避免出现[2,5,5],返回[[2,5],[2,5]]这样的结果。
class Solution:
def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
mydict ={}
for i in range(len(nums)):
num =target-nums[i]
if num not in mydict:
mydict[nums[i]]=i
else:
return [mydict[num],i]
----------
三数之和
> 给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。
>
> 注意:答案中不可以包含重复的三元组。
>
> 例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4],
>
> 满足要求的三元组集合为:
> [
> [-1, 0, 1],
> [-1, -1, 2]
> ]
思路:
想要找到满足a+b+c=0的元素,等价于找到a+b=-c的元素,最简单的思路是三层循环遍历求解,但是由于其高额的时间复杂度,是我们无法承担的,所以采用一种O(n**2)的方法,减少时间消耗。---双指针法
先排序,从小大,两层循环,外层循环遍历nums = [-1, -1,0, 1, 2, -4],依次取出其中的元素作为-c,因此原题就转化为了在列表nums中寻找其他两个**不同**的元素使得a+b=-c。**为什么要排序呢?这里解释一下,先进行从小到大的排序,那么每次取出一个元素,我们假设这是取出的三个数中的最小的元素,那么为了满足等式要求,就需要找到另外两个较大的数,而这两个较大的数,此时必然在列表的右边,这样一来,就不需要经历从头到尾的遍历了。**内层循环设立两个指针,分别指向-c的下一位与列表最后一位(**较大的两个数**)当a大于0的时候,a,b,c就都大于0了,此时应该结束寻找。通过上述多次剪枝,我们大大降低了算法的执行时间。
class Solution:
def threeSum(self, nums):
"""
a+b+c =0 ==> a+b = -c
双指针法,fix 一个数,用双指针法去寻找另外两个数
两个指针分别指向,fix数字之后开始的数组首尾两个数
两数之和大于target,右边的指针左移一位
两数之和小于target,左边的指针右移一位
+剪枝优化:假设当前的target大于0 ,那么break
假设当前target的值与前面target的值相等那么退出本次循环,
赋值会大大增加程序运行时间
"""
length =len(nums)
res =[]
if length>2:
nums =sorted(nums)
for i in range(length-2):
target= nums[i]
if target>0:
break
if i>0 and nums[i]==nums[i-1]:
continue
left =i+1
right =length-1
while left<right:
val =nums[right]+nums[left]
if val==-target:
res.append([target,nums[left],nums[right]])
#相同的元素忽略,以免返回重复的结果
while left<right and nums[left]==nums[left+1]:
left+=1
while left<right and nums[right]==nums[right-1]:
right-=1
left+=1
right-=1
elif val>-target:
right-=1
else:
left+=1
return res
else:
return res