这是在http://blog.csdn.net/insistgogo/article/details/12187329里面看到的一道题,自己拿来做一做。只做加法的部分吧。
我想到的一个思路就是对于
1,3,5,7,9
2,4,6,8,10
这两个序列,肯定是1+2是最小的,然后1+4<3+4,2+3<3+4,所以可以按照归并的思想从小到大把所有的结果都存储在一个数组中。
这个方法虽然时间复杂度低,但是需要的额外空间也不少,而且编起来也很麻烦。
对于求前k个最小值,自然是使用最大堆了。那到底有没有必要使用暴力解法呢?实际上对每个数字之和,还是要遍历一遍的,比如
1,2,3,4,5,6,7
10,10,10,10,10,10
就必须要全部遍历一遍,所以不能求出n^2 >= k的下标就了事。
但是题目本身来说还是可以进行优化的,因为是有序数组,所以左边的数相加肯定比右边的数相加要小。所以如果A的元素乘以B的元素比最大堆中的数还要大,那么可以肯定A以后的元素和B以后的元素相加肯定是要比最大堆中的数要大了,所以这个时候就可以退出了。
具体代码:
#ifndef _KTH_SAMLLEST_H_
#define _KTH_SAMLLEST_H_
#include <iostream>
#include <vector>
using namespace std;
vector<int> A;
vector<int> B;
typedef struct containter
{
int a;
int b;
int res;
containter(int a_, int b_)
: a(a_), b(b_), res(a_+b_){}
const bool operator<(const containter& rhs) const
{
return this->res < rhs.res;
}
}container_t;
vector<container_t> heap;
const size_t K = 10;
//插入到最大堆中
const bool insert_heap(int a, int b)
{
container_t c(a, b);
if (! (c < heap[0]) )
{//
return false;
}
size_t hole = 0;
for (size_t child; child = hole*2+1, child < heap.size(); hole = child)
{//
if (child + 1 < heap.size() && heap[child] < heap[child+1])
{//
child++;
}
if (heap[child] < c)
{//
break;
}
heap[hole] = heap[child];
}
heap[hole] = c;
return true;
}
void solution()
{
heap.reserve(K);
for (size_t i = 0; i < K; i++)
{//
container_t c(1000,1000);
heap.push_back(c);
}
size_t k = 0;
size_t ptrA = 0, ptrB = 0, ptr;
int mul;
vector<int>& rep = A;
while (true)
{//
if (A[ptrA] > B[ptrB])
{//
mul = A[ptrA++];
rep = B;
ptr = ptrB;
}
else
{
mul = B[ptrB++];
rep = A;
ptr = ptrA;
}
//剪枝
int first = mul*rep[ptr];
if (heap[0].res < first)
{//结束
return;
}
for (; ptr < rep.size(); ptr++)
{//
if (!insert_heap(mul, rep[ptr]))
{//剪枝
break;
}
}
}
}
void print_()
{
for (size_t i = heap.size()-1; i != 0; i--)
{//
swap(heap[0], heap[i]);
size_t hole = 0;
container_t tmp = heap[0];
for (size_t child; child = hole*2+1, child < i; hole = child)
{//
if (child + 1 < heap.size() && heap[child] < heap[child+1])
{//
child++;
}
if (heap[child] < tmp)
{//
break;
}
heap[hole] = heap[child];
}
heap[hole] = tmp;
}
for (size_t i = 0; i < heap.size(); i++)
{//
cout << heap[i].a << " + " << heap[i].b << " = " << heap[i].res << endl;
}
}
void tester()
{
for (int i = 1; i < 10; i += 2)
{//
A.push_back(i);
}
for (int i = 2; i <= 10; i += 2)
{//
B.push_back(i);
}
solution();
print_();
}
#endif