**16. 3Sum Closest

1. 原始题目

给定一个包括 n 个整数的数组 nums 和 一个目标值 target。找出 nums 中的三个整数,使得它们的和与 target 最接近。返回这三个数的和。假定每组输入只存在唯一答案。

例如,给定数组 nums = [-1,2,1,-4], 和 target = 1.

与 target 最接近的三个数的和为 2. (-1 + 2 + 1 = 2).

2. 分析

本题是最近的三数之和,与15题三数之和很类似,不同之处有这么几点:

1)三数之和要求和为0,本题要求三数之和与提供的一个target最近。也就是说和不一定为target,只要找出绝对值最小的即可。

2)三数之和需要去重复,本题只要找出最小距离就行。

3)本题如果找到和target距离为0的三个数时即可停止寻找,返回结果就行。因为三数与target最小距离也只能是0,没必要再去寻找。除非题目要求找出与target距离最近的所有的三数。

 

3. 解题

 1 class Solution:
 2     def threeSumClosest(self, nums, target):
 3         if len(nums)<3: return []
 4         results = abs(nums[0]+nums[1]+nums[2]-target)       # 首先设立一个基准初始值。假定开头三个数的距离最小,记在results里,后面与他作比较
 5         sss=[nums[0],nums[1],nums[2]]                       # 记录基准初始值的三个数,之后如果有更好的结果也会更新此值       
 6         L = sorted(nums)       # 排序                              
 7         
 8         for i in range(len(L)):      
10             head = i+1                # head指向i下一个位置
11             tail = len(L)-1           # tail指向尾部
12             while(head<tail):         # 若未相遇              
13 #                print(L[i],L[head],L[tail])
14                 if abs(L[head]+L[tail]+L[i]-target)<results:   # 如果又更小的距离
15                     results = abs(L[head]+L[tail]+L[i]-target)    # 更新距离
16                     sss=[L[head],L[tail],L[i]]                    # 更新三数
17                 if L[head]+L[tail]+L[i]-target==0:                # 另外如果相距为0的话,直接返回,没必要再找了 
18                     return sum(sss)
19                 if L[head]+L[tail]+L[i]-target>0:                 # 如果此时他们的和大于0,我们希望它靠近于0呀,所以尾部左移,减小他们的和 
20                     tail-=1
21                 else:
22                     head+=1                                       # 如果此时他们的和小于0,我们希望它靠近与0呀。所以头部右移,增大他们的和
23             i+=1
24         return sum(sss)

 

posted @ 2019-04-10 14:58  三年一梦  阅读(108)  评论(0编辑  收藏  举报