How to get the K smallest Products from pairs from two sorted Arrays?

前端 未结 2 1355
小蘑菇
小蘑菇 2021-01-14 03:51

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

2条回答
  •  猫巷女王i
    2021-01-14 04:36

    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 = [].

    1. Add the first pair p = (i j) of P to R.

    2. If R is of size k, terminate.

    3. 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.

    4. 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.

提交回复
热议问题