两有序数组两两之和的最小k个值, 最小堆解法之完整版

原题: 给定两有序数组,长度都是n,在总共n^2个两两之和中,找到最小的k个值。

题目不新鲜,出现了也有很多年了,不过在目前的面试中还有使用。较好的方法显然是用最小堆,时间复杂度降到 O(klgk)不过网上大略搜了一下,没有找到完整实现,甚至连关键点都没提到,我这里就算是个补充吧。

用最小堆,元素是 A[i] + B[j]. 每次弹出堆顶,然后插入新元素,维护最小堆。这里的关键在于每次插入哪些元素。大多数人说的都是,对于弹出A[i] + B[j], 应该插入A[i+1] + B[j], 以及A[i] + B[j+1]。我们来看看事实是什么。


已有A,B 两数组,假设从0开始升序排列。

如果当前最小堆弹出了A[1]+B[0], 那么接下来显然应该插入A[1] + B[1], 同时还有A[2] + B[0]. A[3]以上的组合不必考虑,因为A[2] + B[0]才刚刚插入。

如果当前弹出了A[1] + B[1], 那么插入A[1] + B[2]. 还有其他要插的么? 其实已经没还有了。由于A[2] + B[0]已在堆中还未弹出,所以A[3] 以上的组合全都不用入堆。

简单列个表格如下, 弹出项除(0,0)外全都是假设:

selected(i, j)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值