LeetCode 16 3Sum Closest 可用三分法

题意:3Sum题变种,给出n个数nums[]和一个target,求n中的3个数的组合使得其和与target相差值最小。

思路:传统的3Sum做法(LeetCode15),枚举三个数中的两个,然后求证剩余的数字是否在给出的集合中。后面一步可以时间换空间,用二分来做,这样复杂度乘上一个logn;也可以空间换时间,用数组直接存储或者hash挂链。

对于这一题,可以继续用传统的解法,先枚举三个数中的两个,但注意到目标答案的变化并不是单调的,即取出两个数nums[i]和nums[j]后,最优解的计算过程为ans=f(v)=min(target-nums[i]-nums[j]-v),这个关于v的函数是先减后增的,是一个经典的可以使用三分法计算最优解的模型。

很久没有写三分了,可能别人有更好的写法,这里介绍一种常数可能高一点但一定不会错的写法:

  1. 首先取l,r,得到端点间距离d=r-l;
  2. 如果d<3,退出循环,将l到r的每个点对应的值直接算出来从而对答案进行维护;
  3. 否则机算三等分的长度len=d/3,取p1=l+len,p2=r-len;
  4. 因为len=d/3<=(double)d/3,再加上之前d>=3时的约束,可以保证p1<p2;
  5. 比较f(p1)与f(p2)的大小,取较高者进行三分;

关于第5步取较高点的原因,下图即为例子:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值