题目描述:
Let A and B are sorted array with length m and n respectively, given k, the problem is to find the first k smallest elements which are composed of A[i]+B[j].
e.g.
A={1,3,5,7}, B={2,6, 10}, k = 3
Output:
1+2
3+2
1+6
分析:
不晓得有没有时间复杂度更小的算法,目前只想到用堆来实现,时间复杂度为O(klgk)
use a min-heap of pairs (ik,jk), using ordering on A[ik] + B[jk]
Initialize the heap with pairs (ik=k, jk=0) for k=0..n-1
On removing (ix,jx), replace it with (ix,jx+1)
代码实现:
template <typename T>
class Sum
{
T a;
T b;
public:
Sum(T a,T b)
{
this->a=a;
this->b=b;
};
T getSum() const
{
return a+b;
};
void print()
{
cout<<endl<<"("<<a<<"+"<<b<<")"<<endl;
};
/////自定义数据想用functional函数less<>,greater<>,必须重载< 或 >操作符
friend bool operator > (const Sum<T>& s1,const Sum<T>& s2);
};
/////
bool operator > (const Sum<int>& s1,const Sum<int>& s2)
{
return s1.getSum()>s2.getSum();
}
int main()
{
vector<Sum<int> > vSum;
int A[]={1,2,3};
int B[]={2,3,4,5};
int k=7;
int count=0;
int m,n;
int sizeA=sizeof(A)/sizeof(int);
int sizeB=sizeof(B)/sizeof(int);
for(m=0;m<sizeA;m++)
{
for(n=0;n<sizeB;n++)
{
if(count!=k)
{
vSum.push_back(Sum<int>(A[m],B[n]));
count++;
}
else
break;
}
if(count==k)
break;
}
make_heap(vSum.begin(),vSum.end(),greater<Sum<int> >());
count=0;
m=k/sizeA-1;
n=k%sizeB;
for(;m<sizeA;m++)
{
for(;n<sizeB;n++)
{
pop_heap(vSum.begin(),vSum.end(),greater<Sum<int> >());
/////pop非真正pop,放在容器末尾
vSum.back().print();
vSum.pop_back();
count++;
if(count==k)
{
break;
}
vSum.push_back(Sum<int>(A[m],B[n]));
push_heap(vSum.begin(),vSum.end(),greater<Sum<int> >());
}
if(count==k)
break;
if(n==4)
n=0;
}
////所用的Sum对象push_heap之后,还未输出足够需要的Sum,则继续pop_heap
while(count<k)
{
pop_heap(vSum.begin(),vSum.end(),greater<Sum<int> >());
vSum.back().print();
vSum.pop_back();
count++;
}
system("pause");
return 0;
}
运行结果: