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 notbool 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 Codeint32_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 approachimport java.util.*;Â
class GFG{Â
Â
// Function to check if count of elements// greater than req in product array are// more than K or notstatic 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 Codepublic 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 approachLLONG_MAX = 9223372036854775807LLONG_MIN = -9223372036854775807Â
# Function to check if count of elements# greater than req in product array are# more than K or notdef 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 Codeif __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 approachusing 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 notfunction 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 Codelet 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!
