Two sorted arrays are given. We have to find the K smallest products from the pairs from these arrays. I could think of a mnlogk solution but this solution works ev
Here is an algorithm that has O(k min(n, m)) time complexity.
Let A and B be sorted lists of integers, i.e. A = [a1 a2 a3 ... am] with ai ≤ ai+1, and B = [b1 b2 b3 ... bn] with bi ≤ bi+1.
Assume for now that ai ≥ 0 and bi ≥ 0. We will show below how to account for negative integers.
Let p = (i j) be a pair, where i and j are the indexes of ai and bj. Let P be a list of pairs. Set P = [(1 1) (1 2) (1 3) ... (1 n)]. Assume k > 0 (and k ≤ m x n). Let R be the list of the pairs of the k first products. Initialize R = [].
Add the first pair p = (i j) of P to R.
If R is of size k, terminate.
Set p = (i+1 j). While the product of p is greater than the product of the next pair q in P, exchange p and q.
Go to step 1.
The above algorithm has time complexity O(k n) and works for A and B containing non-negative integers only. Note that if m < n, we can exchange A and B to get a lower bound on the time complexity.
Here is an example that illustrates the algorithm with A = [2 6 13] and B = [1 6 9]. The matrix below shows the product ai x bj for every (i j).
B 1 6 9
A ------------
2 | 2 12 18
6 | 6 36 54
13 | 13 78 117
This is the initial states of P and R at the start of the alogrithm. We suffix each pair (i j) in P with the value of the product ai x bj.
P = [(1 1):2 (1 2):12 (1 3):18] R = []
On the first iteration, (1 1):2 is added to R, and the first pair in P becomes (1+1 1).
R = [(1 1):2]
P = [(2 1):6 (1 2):12 (1 3):18]
On the next iteration, (2 1):6 is added to R, and the first pair in P becomes (2+1 1). Because the product of that pair is greater than the product of the next pair in P, they are exchanged.
R = [(1 1):2 (2 1):6]
P = [(3 1):13 (1 2):12 (1 3):18]
P = [(1 2):12 (3 1):13 (1 3):18]
Next iteration, similar operations as the previous iteration.
R = [(1 1):2 (2 1):6 (1 2):12]
P = [(2 2):36 (3 1):13 (1 3):18]
P = [(3 1):13 (1 3):18 (2 2):36]
In this iteration, after adding (3 1):13 to R, the first pair of P becomes (3+1 1), but that pair does not exist. So, it is simply removed from P.
R = [(1 1):2 (2 1):6 (1 2):12 (3 1):13]
P = [(1 3):18 (2 2):36]
Following are all remaining iterations until P is empty.
R = [(1 1):2 (2 1):6 (1 2):12 (3 1):13 (1 3):18]
P = [(2 3):54 (2 2):36]
P = [(2 2):36 (2 3):54]
R = [(1 1):2 (2 1):6 (1 2):12 (3 1):13 (1 3):18 (2 2):36]
P = [(3 2):78 (2 3):54]
P = [(2 3):54 (3 2):78]
R = [(1 1):2 (2 1):6 (1 2):12 (3 1):13 (1 3):18 (2 2):36 (2 3):54]
P = [(3 3):117 (3 2):78]
P = [(3 2):78 (3 3):117]
R = [(1 1):2 (2 1):6 (1 2):12 (3 1):13 (1 3):18 (2 2):36 (2 3):54 (3 2):78]
P = [(3 3):117]
R = [(1 1):2 (2 1):6 (1 2):12 (3 1):13 (1 3):18 (2 2):36 (2 3):54 (3 2):78 (3 3):117]
P = []
Now, if A and B contain both non-negative and negative integers, we can use the above algorithm to solve at most 4 sub-problems concurrently to get the k smallest integers. For this, we define the iterator function F(A, B) that on each call yields the next product in increasing order using the above algorithm. Let A- and A+ be the sublists of A containing its negative and non-negative integers respectively. Same thing for B- and B+. We call our iterator function for the following 4 sub-problems.
F(A+, B+)
F(A+, reverse(B-))
F(reverse(A-), B+)
F(reverse(A-), reverse(B-))
where reverse(L) returns list L with its elements in reverse order. We iterate over these four iterators choosing the k smallest returned pairs.