看到这个题是不是有点熟悉 如果之前看过我的博客的话我是有写过三数之和等于固定值的 那既然遇到这道题 大家就一起练习一下
给你一个长度为 n
的整数数组 nums
和 一个目标值 target
。请你从 nums
中选出三个整数,使它们的和与 target
最接近。
返回这三个数的和。
假定每组输入只存在恰好一个解。
但是这个不考虑重复的问题 所以咱不需要去重 之前的三数之和是将所有的情况都存储下来 所以我是使用三重循坏并没有超过时间限制 但是这个不像三个元素加起来等于固定值就可以返回 不是这么简单的 是找到最优的 所以这次我使用三重循环就导致超时 大家如果不想看整个过程可以直接看代码3 (点击目录)
给大家看一下我最开始写的 这个代码是错误的 首先是我改了target的值 而且很早就return 了 没有找到全局最优解 之所以没有找到全局最优解,是因为它只检查了第一个 (i, j)
组合,然后直接 return
,而没有遍历所有可能的 (i, j, k)
组合
代码1
class Solution(object):
def threeSumClosest(self, nums, target):
for i in range(len(nums)-2):
for j in range(i+1,len(nums)-1):
min_min=float('inf')
s=0
target=target-(nums[i]+nums[j])
for k in range(j+1,len(nums)):
current_min=abs(nums[k]-target)
if current_min<min_min:
min_min=current_min
s=k#找最接近的
return nums[i]+nums[j]+nums[s]
solution=Solution()
result=solution.threeSumClosest([0,0,0],1)
print(result)
所以正确的思路应该是我在这个k之中得到这一轮i j k的最好的结果 然后存储下来 再进行全局的一个筛选 找到全局的之和最接近target的和 最后return return 一定是和for i是平行的位置的 接下来我会将我写的代码每句加上注释
代码2
class Solution(object):
def threeSumClosest(self, nums, target):
closest_sum = float('inf') # 初始化最接近的和 初始化为最大值
min_min = float('inf') # 初始化最小差值
for i in range(len(nums)-2):
for j in range(i+1,len(nums)-1):
current_min1 = float('inf')#这一轮的最小值
s=0#记录K的值
remaining_target=target-(nums[i]+nums[j])#此轮 target减去i j 之和
#这里是此轮 i j k 在固定一轮 i j 之后 遍历k 找到最合适的current_sum
for k in range(j+1,len(nums)):
current_min=abs(nums[k]-remaining_target)
if current_min<current_min1:
current_min1=current_min
s=k#找最接近的
current_sum=nums[i]+nums[j]+nums[s]#这是一轮下来的结果
#这里是全局 也就是所有的i j 组合得到的当前的和进行比较 找出来一个与target差距最小的和
if abs((current_sum)-target)<min_min:
min_min=abs((current_sum)-target)
closest_sum=current_sum
return closest_sum#return一定是在最外层 和for i 是并列的 这样找到的才是全局的最优解
solution=Solution()
result=solution.threeSumClosest([4,0,5,-5,3,3,0,-4,-5],-2)
print(result)
在Pycharm中是可以运行成功通过各种测试的 但是在平台测试就显示超时 那我们就使用指针的方法去寻找最合适的解
思路是这样的:我会存储当前的三数之和和当前的差值 再去和整体的差值进行对比 这样可以更改最小的差值 同时三数之和也要进行更新 注意我们是需要更新的 更新的条件是什么呢?就是将target-nums[i]与两个数之和进行对比 所以我们需要一个变量存储左指针+右指针的和 这样方便我们去移动指针 最好的情况就是直接三者之和加起来等于target直接return 或者等全部都比较完之后return 最小的差值所对应的三数之和
你需要的是当前的两个和 得到差值 当前的三个值之和
你需要比较的是 当前的差值和整体的差值哪个是最小的 你需要更改的是此时最小的差值所对应的三个数之和 我觉得这道题烦人的点就是变量太多 最好列个小表格知道需要记录什么 更新什么 怎么得到 这样就比较明朗了
代码3
class Solution(object): def threeSumClosest(self, nums, target): nums=sorted(nums) min_sum=float('inf')#整体之和 min_1=float('inf')#整体差值 for i in range(len(nums)): left=i+1 right=len(nums)-1 current_target=target-nums[i] while left<right: current_two_sum=nums[left]+nums[right]#两个数之和 用于后续移动 current_total_sum=nums[left]+nums[right]+nums[i]#当前三数之和,用于更新对应最小差值的整体之和 current_total_diff=abs(current_total_sum-target)#当前三数之和与target的差值 用于更新整体最小的差值 if current_total_diff<min_1: min_1=current_total_diff min_sum=current_total_sum#反正我会把最合适的存好 if current_two_sum<current_target:#进行移动 left+=1 elif current_two_sum>current_target: right-=1 else: return target return min_sum solution=Solution() result=solution.threeSumClosest([-1,2,1,-4],1) print(result)
但是我这个运行结果不好 用时击败39% 内存消耗击败70多% 我打算先放在这里留个坑 之后如果我能想到比排序+双指针更好的方法的话再来更新这篇