Given two sorted arrays A[] and B[] consisting of N and M integers respectively, the task is to find the Kth smallest number in the array formed by the product of all possible pairs from array A[] and B[] respectively.
Examples:
Input: A[] = {1, 2, 3}, B[] = {-1, 1}, K = 4
Output: 1
Explanation: The array formed by the product of any two numbers from array A[] and B[] respectively is prod[] = {-3, -2, -1, 1, 2, 3}. Hence, the 4th smallest integer in the prod[] array is 1.Input: A[] = {-4, -2, 0, 3}, B[] = {1, 10}, K = 7
Output: 3
Approach: The given problem can be solved with the help of Binary Search over all possible values of products. The approach discussed here is very similar to the approach discussed in this article. Below are the steps to follow:
- Create a function check(key), which returns whether the number of elements smaller than the key in the product array is more than K or not. It can be done using the two-pointer technique similar to the algorithm discussed in the article here.
- Perform a binary search over the range [INT_MIN, INT_MAX] to find the smallest number ans such that the number of elements smaller than ans in the product array is at least K.
- After completing the above steps, print the value of ans as the result.
Below is the implementation of the above approach:
C++
// C++ program for the above approach #include <bits/stdc++.h> using namespace std; #define int long long Â
// Function to check if count of elements // greater than req in product array are // more than K or not bool check( int req, vector< int > posA,            vector< int > posB, vector< int > negA,            vector< int > negB, int K) {     // Stores the count of numbers less     // than or equal to req     int cnt = 0; Â
    // Case with both elements of A[] and     // B[] are negative     int first = 0;     int second = negB.size() - 1; Â
    // Count number of pairs formed from     // array A[] and B[] with both elements     // negative and there product <= req     while (first < negA.size()) {         while (second >= 0                && negA[first]                           * negB[second]                       <= req)             second--; Â
        // Update cnt         cnt += negB.size() - second - 1;         first++;     } Â
    // Case with both elements of A[] and     // B[] are positive     first = 0;     second = posB.size() - 1; Â
    // Count number of pairs formed from     // array A[] and B[] with both elements     // positive and there product <= req     while (first < posA.size()) {         while (second >= 0                && posA[first]                           * posB[second]                       > req)             second--; Â
        // Update cnt         cnt += second + 1;         first++;     } Â
    // Case with elements of A[] and B[]     // as positive and negative respectively     first = posA.size() - 1;     second = negB.size() - 1; Â
    // Count number of pairs formed from     // +ve integers of A[] and -ve integer     // of array B[] product <= req     while (second >= 0) {         while (first >= 0                && posA[first]                           * negB[second]                       <= req)             first--; Â
        // Update cnt         cnt += posA.size() - first - 1;         second--;     } Â
    // Case with elements of A[] and B[]     // as negative and positive respectively     first = negA.size() - 1;     second = posB.size() - 1; Â
    // Count number of pairs formed from     // -ve and +ve integers from A[] and     // B[] with product <= req     for (; first >= 0; first--) {         while (second >= 0                && negA[first]                           * posB[second]                       <= req)             second--; Â
        // Update cnt         cnt += posB.size() - second - 1;     } Â
    // Return Answer     return (cnt >= K); } Â
// Function to find the Kth smallest // number in array formed by product of // any two elements from A[] and B[] int kthSmallestProduct(vector< int >& A, Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â vector< int >& B, Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â int K) { Â Â Â Â vector< int > posA, negA, posB, negB; Â
    // Loop to iterate array A[]     for ( const auto & it : A) {         if (it >= 0)             posA.push_back(it);         else             negA.push_back(it);     } Â
    // Loop to iterate array B[]     for ( const auto & it : B)         if (it >= 0)             posB.push_back(it);         else             negB.push_back(it); Â
    // Stores the lower and upper bounds     // of the binary search     int l = LLONG_MIN, r = LLONG_MAX; Â
    // Stores the final answer     int ans; Â
    // Find the kth smallest integer     // using binary search     while (l <= r) { Â
        // Stores the mid         int mid = (l + r) / 2; Â
        // If the number of elements         // greater than mid in product         // array are more than K         if (check(mid, posA, posB,                   negA, negB, K)) {             ans = mid;             r = mid - 1;         }         else {             l = mid + 1;         }     } Â
    // Return answer     return ans; } Â
// Driver Code int32_t main() { Â Â Â Â vector< int > A = { -4, -2, 0, 3 }; Â Â Â Â vector< int > B = { 1, 10 }; Â Â Â Â int K = 7; Â
    cout << kthSmallestProduct(A, B, K); Â
    return 0; } |
Java
// Java program for the above approach import java.util.*; Â
class GFG{ Â
Â
// Function to check if count of elements // greater than req in product array are // more than K or not static boolean check( int req, Vector<Integer> posA,            Vector<Integer> posB, Vector<Integer> negA,            Vector<Integer> negB, int K) {        // Stores the count of numbers less     // than or equal to req     int cnt = 0 ; Â
    // Case with both elements of A[] and     // B[] are negative     int first = 0 ;     int second = negB.size() - 1 ; Â
    // Count number of pairs formed from     // array A[] and B[] with both elements     // negative and there product <= req     while (first < negA.size()) {         while (second >= 0                && negA.elementAt(first)                           * negB.elementAt(second)                       <= req)             second--; Â
        // Update cnt         cnt += negB.size() - second - 1 ;         first++;     } Â
    // Case with both elements of A[] and     // B[] are positive     first = 0 ;     second = posB.size() - 1 ; Â
    // Count number of pairs formed from     // array A[] and B[] with both elements     // positive and there product <= req     while (first < posA.size()) {         while (second >= 0                && posA.elementAt(first)                           * posB.elementAt(second)                       > req)             second--; Â
        // Update cnt         cnt += second + 1 ;         first++;     } Â
    // Case with elements of A[] and B[]     // as positive and negative respectively     first = posA.size() - 1 ;     second = negB.size() - 1 ; Â
    // Count number of pairs formed from     // +ve integers of A[] and -ve integer     // of array B[] product <= req     while (second >= 0 ) {         while (first >= 0                && posA.elementAt(first)                           * negB.elementAt(second)                       <= req)             first--; Â
        // Update cnt         cnt += posA.size() - first - 1 ;         second--;     } Â
    // Case with elements of A[] and B[]     // as negative and positive respectively     first = negA.size() - 1 ;     second = posB.size() - 1 ; Â
    // Count number of pairs formed from     // -ve and +ve integers from A[] and     // B[] with product <= req     for (; first >= 0 ; first--) {         while (second >= 0                && negA.elementAt(first)                           * posB.elementAt(second)                       <= req)             second--; Â
        // Update cnt         cnt += posB.size() - second - 1 ;     } Â
    // Return Answer     return (cnt >= K); } Â
// Function to find the Kth smallest // number in array formed by product of // any two elements from A[] and B[] static int kthSmallestProduct( int [] A,                        int [] B,                        int K) {     Vector<Integer> posA = new Vector<>();     Vector<Integer> negA = new Vector<>();     Vector<Integer> posB = new Vector<>();     Vector<Integer> negB = new Vector<>();     // Loop to iterate array A[]     for ( int  it : A) {         if (it >= 0 )             posA.add(it);         else             negA.add(it);     } Â
    // Loop to iterate array B[]     for ( int it : B)         if (it >= 0 )             posB.add(it);         else             negB.add(it); Â
    // Stores the lower and upper bounds     // of the binary search     int l = Integer.MIN_VALUE, r = Integer.MAX_VALUE; Â
    // Stores the final answer     int ans= 0 ; Â
    // Find the kth smallest integer     // using binary search     while (l <= r) { Â
        // Stores the mid         int mid = (l + r) / 2 ; Â
        // If the number of elements         // greater than mid in product         // array are more than K         if (check(mid, posA, posB,                   negA, negB, K)) {             ans = mid;             r = mid - 1 ;         }         else {             l = mid + 1 ;         }     } Â
    // Return answer     return ans; } Â
// Driver Code public static void main(String[] args) { Â Â Â int [] A = { - 4 , - 2 , 0 , 3 }; Â Â Â Â int [] B = { 1 , 10 }; Â Â Â Â int K = 7 ; Â
    System.out.print(kthSmallestProduct(A, B, K)); Â
} } Â
// This code is contributed by gauravrajput1 |
Python3
# python program for the above approach LLONG_MAX = 9223372036854775807 LLONG_MIN = - 9223372036854775807 Â
# Function to check if count of elements # greater than req in product array are # more than K or not def check(req, posA, posB, negA, negB, K): Â
    # Stores the count of numbers less     # than or equal to req     cnt = 0 Â
    # Case with both elements of A[] and     # B[] are negative     first = 0     second = len (negB) - 1 Â
    # Count number of pairs formed from     # array A[] and B[] with both elements     # negative and there product <= req     while (first < len (negA)):         while (second > = 0 and negA[first] * negB[second] < = req):             second - = 1 Â
        # Update cnt         cnt + = len (negB) - second - 1         first + = 1 Â
    # Case with both elements of A[] and     # B[] are positive     first = 0     second = len (posB) - 1 Â
    # Count number of pairs formed from     # array A[] and B[] with both elements     # positive and there product <= req     while (first < len (posA)):         while (second > = 0 and posA[first] * posB[second] > req):             second - = 1 Â
        # Update cnt         cnt + = second + 1         first + = 1 Â
    # Case with elements of A[] and B[]     # as positive and negative respectively     first = len (posA) - 1     second = len (negB) - 1 Â
    # Count number of pairs formed from     # +ve integers of A[] and -ve integer     # of array B[] product <= req     while (second > = 0 ):         while (first > = 0 and posA[first] * negB[second] < = req):             first - = 1 Â
        # Update cnt         cnt + = len (posA) - first - 1         second - = 1 Â
    # Case with elements of A[] and B[]     # as negative and positive respectively     first = len (negA) - 1     second = len (posB) - 1 Â
    # Count number of pairs formed from     # -ve and +ve integers from A[] and     # B[] with product <= req     for first in range (first, - 1 , - 1 ):         while (second > = 0 and negA[first] * posB[second] < = req):             second - = 1 Â
        # Update cnt         cnt + = len (posB) - second - 1 Â
    # Return Answer     return (cnt > = K) Â
Â
# Function to find the Kth smallest # number in array formed by product of # any two elements from A[] and B[] def kthSmallestProduct(A, B, K): Â
    posA = []     negA = []     posB = []     negB = [] Â
    # Loop to iterate array A[]     for it in A:         if (it > = 0 ):             posA.append(it)         else :             negA.append(it) Â
        # Loop to iterate array B[]     for it in B:         if (it > = 0 ):             posB.append(it)         else :             negB.append(it) Â
        # Stores the lower and upper bounds         # of the binary search     l = LLONG_MIN     r = LLONG_MAX Â
    # Stores the final answer     ans = 0 Â
    # Find the kth smallest integer     # using binary search     while (l < = r): Â
        # Stores the mid         mid = (l + r) / / 2 Â
        # If the number of elements         # greater than mid in product         # array are more than K         if (check(mid, posA, posB, negA, negB, K)):             ans = mid             r = mid - 1         else :             l = mid + 1 Â
        # Return answer     return ans Â
Â
# Driver Code if __name__ = = "__main__" : Â
    A = [ - 4 , - 2 , 0 , 3 ]     B = [ 1 , 10 ]     K = 7 Â
    print (kthSmallestProduct(A, B, K)) Â
    # This code is contributed by rakeshsahni |
C#
// C# program for the above approach using System; using System.Collections.Generic; Â
public class GFG { Â
    // Function to check if count of elements     // greater than req in product array are     // more than K or not     static bool check( int req, List< int > posA, List< int > posB, List< int > negA,             List< int > negB, int K) { Â
        // Stores the count of numbers less         // than or equal to req         int cnt = 0; Â
        // Case with both elements of []A and         // []B are negative         int first = 0;         int second = negB.Count - 1; Â
        // Count number of pairs formed from         // array []A and []B with both elements         // negative and there product <= req         while (first < negA.Count) {             while (second >= 0 && negA[first]                           * negB[second] <= req)                 second--; Â
            // Update cnt             cnt += negB.Count - second - 1;             first++;         } Â
        // Case with both elements of []A and         // []B are positive         first = 0;         second = posB.Count - 1; Â
        // Count number of pairs formed from         // array []A and []B with both elements         // positive and there product <= req         while (first < posA.Count) {             while (second >= 0 && posA[first] * posB[second] > req)                 second--; Â
            // Update cnt             cnt += second + 1;             first++;         } Â
        // Case with elements of []A and []B         // as positive and negative respectively         first = posA.Count - 1;         second = negB.Count - 1; Â
        // Count number of pairs formed from         // +ve integers of []A and -ve integer         // of array []B product <= req         while (second >= 0) {             while (first >= 0 && posA[first] * negB[second] <= req)                 first--; Â
            // Update cnt             cnt += posA.Count - first - 1;             second--;         } Â
        // Case with elements of []A and []B         // as negative and positive respectively         first = negA.Count - 1;         second = posB.Count - 1; Â
        // Count number of pairs formed from         // -ve and +ve integers from []A and         // []B with product <= req         for (; first >= 0; first--) {             while (second >= 0 && negA[first]* posB[second]<= req)                 second--; Â
            // Update cnt             cnt += posB.Count - second - 1;         } Â
        // Return Answer         return (cnt >= K);     } Â
    // Function to find the Kth smallest     // number in array formed by product of     // any two elements from []A and []B     static int kthSmallestProduct( int [] A, int [] B, int K) {         List< int > posA = new List< int >();         List< int > negA = new List< int >();         List< int > posB = new List< int >();         List< int > negB = new List< int >();         // Loop to iterate array []A         foreach ( int it in A) {             if (it >= 0)                 posA.Add(it);             else                 negA.Add(it);         } Â
        // Loop to iterate array []B         foreach ( int it in B)             if (it >= 0)                 posB.Add(it);             else                 negB.Add(it); Â
        // Stores the lower and upper bounds         // of the binary search         int l = int .MinValue, r = int .MaxValue; Â
        // Stores the readonly answer         int ans = 0; Â
        // Find the kth smallest integer         // using binary search         while (l <= r) { Â
            // Stores the mid             int mid = (l + r) / 2; Â
            // If the number of elements             // greater than mid in product             // array are more than K             if (check(mid, posA, posB, negA, negB, K)) {                 ans = mid;                 r = mid - 1;             } else {                 l = mid + 1;             }         } Â
        // Return answer         return ans;     } Â
    // Driver Code     public static void Main(String[] args) {         int [] A = { -4, -2, 0, 3 };         int [] B = { 1, 10 };         int K = 7; Â
        Console.Write(kthSmallestProduct(A, B, K)); Â
    } } Â
// This code is contributed by gauravrajput1 |
Javascript
<script> // Javascript program for the above approach Â
// Function to check if count of elements // greater than req in product array are // more than K or not function check(req, posA, posB, negA, negB, K) { Â
  // Stores the count of numbers less   // than or equal to req   let cnt = 0; Â
  // Case with both elements of A[] and   // B[] are negative   let first = 0;   let second = negB.length - 1; Â
  // Count number of pairs formed from   // array A[] and B[] with both elements   // negative and there product <= req   while (first < negA.length) {     while (second >= 0 && negA[first] * negB[second] <= req) second--; Â
    // Update cnt     cnt += negB.length - second - 1;     first++;   } Â
  // Case with both elements of A[] and   // B[] are positive   first = 0;   second = posB.length - 1; Â
  // Count number of pairs formed from   // array A[] and B[] with both elements   // positive and there product <= req   while (first < posA.length) {     while (second >= 0 && posA[first] * posB[second] > req) second--; Â
    // Update cnt     cnt += second + 1;     first++;   } Â
  // Case with elements of A[] and B[]   // as positive and negative respectively   first = posA.length - 1;   second = negB.length - 1; Â
  // Count number of pairs formed from   // +ve integers of A[] and -ve integer   // of array B[] product <= req   while (second >= 0) {     while (first >= 0 && posA[first] * negB[second] <= req) first--; Â
    // Update cnt     cnt += posA.length - first - 1;     second--;   } Â
  // Case with elements of A[] and B[]   // as negative and positive respectively   first = negA.length - 1;   second = posB.length - 1; Â
  // Count number of pairs formed from   // -ve and +ve integers from A[] and   // B[] with product <= req   for (; first >= 0; first--) {     while (second >= 0 && negA[first] * posB[second] <= req) second--; Â
    // Update cnt     cnt += posB.length - second - 1;   } Â
  // Return Answer   return cnt >= K; } Â
// Function to find the Kth smallest // number in array formed by product of // any two elements from A[] and B[] function kthSmallestProduct(A, B, K) { Â Â let posA = [], Â Â Â Â negA = [], Â Â Â Â posB = [], Â Â Â Â negB = []; Â
  // Loop to iterate array A[]   for (it of A) {     if (it >= 0) posA.push(it);     else negA.push(it);   } Â
  // Loop to iterate array B[]   for (it of B)     if (it >= 0) posB.push(it);     else negB.push(it); Â
  // Stores the lower and upper bounds   // of the binary search   let l = Number.MIN_SAFE_INTEGER,     r = Number.MAX_SAFE_INTEGER; Â
  // Stores the final answer   let ans; Â
  // Find the kth smallest integer   // using binary search   while (l <= r)   {        // Stores the mid     let mid = (l + r) / 2; Â
    // If the number of elements     // greater than mid in product     // array are more than K     if (check(mid, posA, posB, negA, negB, K)) {       ans = mid;       r = mid - 1;     } else {       l = mid + 1;     }   } Â
  // Return answer   return ans; } Â
// Driver Code let A = [-4, -2, 0, 3]; let B = [1, 10]; let K = 7; Â
document.write(kthSmallestProduct(A, B, K)); Â
// This code is contributed by gfgking. </script> |
3
Â
Time Complexity: O((N+M)*log 264) or O((N+M)*64)
Auxiliary Space: O(N+M)
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!