Let us denote the 2 sorted lists A (size m) and B (size n).
The algorithm:
- Calculate the sum of A[0] and B[i] for all i = 0 to n - 1. You need to identify which element from list A the sum includes - one way is to attach the index (which is 0 for all sums here). Push all the pairs into a min-heap which is ordered by the sum.
- Pop the heap, and take out the sum. Use the index attached to calculate the sum with the next element in list A. If the index is m - 1 already, no need to do anything; otherwise increment the index and push it back into the heap.
- Repeat step 2 until the heap is empty (for all m * n values).
Step 1 will be O(n log n).
Step 2 is at most O(log n) since the size of the heap may decrease and never increase. Repeating step 2 by m * n times result in time complexity of O(mn log n).
Overall complexity is O(mn log n).
By using the smaller list as list B in the algorithm above, we can achieve a slightly better time complexity (we only need to manage a small heap instead of a big heap).
An implementation using std::priority_queue
(by Stacker):
#include <iostream>
#include <set>
#include <queue>
#include <limits>
std::multiset<int> set1 {4, 8, 19, 25, 25, 26};
std::multiset<int> set2 {1, 2, 3, 8, 20, 27};
struct Node
{
Node(std::multiset<int>::const_iterator set1Iterator, int set2Value) :
set1Iterator(set1Iterator),
set2Value(set2Value),
sum(*set1Iterator + set2Value)
{
}
bool operator < (const Node& other) const
{
return sum > other.sum; // Reverse order as std::priority_queue sorts for the greatest value
}
std::multiset<int>::const_iterator set1Iterator;
int set2Value;
int sum;
};
int main()
{
std::priority_queue<Node> heap;
for (auto i = set2.begin(); i != set2.end(); ++i)
heap.push(Node(set1.begin(), *i));
while (!heap.empty())
{
Node min(heap.top());
heap.pop();
std::cout << *min.set1Iterator << " + " << min.set2Value << " = " <<
min.sum << std::endl;
if (++min.set1Iterator != set1.end())
{
min.sum = *min.set1Iterator + min.set2Value;
heap.push(min);
}
}
return 0;
}