求两个升序序列的和中最小的k个数

这篇博客探讨了如何高效地解决一个数学问题:给定两个升序排列的序列A和B,找出它们对应元素相加后的k个最小和。通过分析有序序列的性质,提出利用有序性避免排序,直接找到i与j的取值来得到最小k个数之和,从而提高算法效率。
摘要由CSDN通过智能技术生成

题目

有两个序列A和B,A=(a1,a2,…,ak),B=(b1,b2,…,bk),A和B都按升序排列。对于1<=i,j<=k,求k个最小的(ai+bj)。要求算法尽量高效。

分析

我们可以使用快速排序或堆排序将相加后的数组进行排序,然后取出最小的k个数即可,但是这样的话,题目中有一个条件没有用到,那就是序列A和序列B都是有序的。如果用上这个条件是不是有更高效的方法呢?

由于序列A和B都是按升序排列,那么假设ai + bj <= C, 那么任意的0 <= p < i and 0 <= q < j,都会有ap + bq <= ai + bj, 因此我们若想找到k个最小的(ai+bj),只需要找到使得(i-1) * j < k或者(j-1) * i < k,当然获得的是其中最小的一个值的情况下的i与j的取值,获取到i与j的值过后,那么p与q的取值相加就是最小的k个和。

代码如下:

#include<iostream>
using namespace std;

int A[] = {3, 9, 12, 20, 23, 34, 39};
int B[] = {1, 10, 15, 19, 25, 39, 47};
int k = sizeof(A)/sizeof(A[0]);
int p, q; 

int *KMinSelect(int *a, int *b, int k){
    int i = k, j = k;
    int count = 0;
    int *
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值