题目
有两个序列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 *