Storing pairwise sums in linear space Storing pairwise sums in linear space arrays arrays

Storing pairwise sums in linear space


The problem, as I understand it, is that we want to find the sums

a1 + b1  a1 + b2  ...  a1 + bna2 + b1  a2 + b2  ...  a2 + bn  ...      ...    ...    ...an + b1  an + b2  ...  an + bn

and print them in sorted order.The restriction is to use only O (n) memory and O (n^2 log n) time in the process.

Consider the above table as n lists (lines) of n elements each.If we sort the initial arrays so that a1 <= a2 <= ... <= an and b1 <= b2 <= ... <= bn, each list is already sorted.Now, the problem is reduced to merging n sorted lists.

To devise that, think of how to merge two sorted lists (as in MergeSort), then three lists, and so on.This extends trivially to merging n lists of length n each in n operations for each output element, for a total of O (n^3).Now, what's left is to reduce time for getting each output element down to O (log n).As you ask for a hint but not a complete solution, see if you can handle that step yourself.


In python you can something like that:

import heapqa = [2, 1, 3]b = [4, 6, 5]a.sort()b.sort()def add_to_b(x):    for v in b:        yield v + xfor v in heapq.merge(*[add_to_b(x) for x in a]):    print v

Result:

566777889

The idea is that we sort both arrays. Then adding to b an element of a defines a generator of increasing numbers. So we create n such generators and we merge them using heapq.merge. A generator, represented by add function above, at a specific time needs constant space (space needed to keep the current position in b). heapq.merge itself needs linear space. So we need linear space for the execution of the algorithm.


First sort the 2 arrays in ascending order, the time complexity is 2 * O(n*lgn), which can be also regarded as O(n*lgn). Then use a max heap with length n + 1 to maintain the minimum n sums.

How to maintain the minimum n sums? First push a1 + b1, a1 + b2, a1 + b3, ..., a1 + bn to the heap. Then for every a[i], 1 <= i < n and b[j], 0 <= j < n, push a[i] + b[j] and then pop the largest one:

for(int j=0;j<n;j++) {    heap.push_into(a[0] + b[j]);}for(int i=1;i<n;i++) {    for(int j=0;j<n;j++) {        heap.push_into(a[i] + b[j]);        heap.pop(); // remove the current largest sum in the heap, then the sums remain in the heap are the smallest n sums    }}

Then the n elements in the heap are the smallest n sums.

The time complexity is O(n^2 * lgn), space complexity is O(n).