Given two arrays arr[] and brr[] containing integers. The task is to find the Kth largest product of a pair (arr[i], brr[j]).
Examples:
Input: arr[] = {1, -2, 3}, brr[] = {3, -4, 0}, K = 3
Output: 3
Explanation: All product combinations in descending order are : [9, 8, 3, 0, 0, 0, -4, -6, -12] and 3rd largest element is 3.Input: arr[] = {-1, -5, -3}, brr[] = {-3, -4, 0}, K =5
Output: 4
Explanation: All product combinations in descending order are : [20, 15, 12, 9, 4, 3, 0, 0, 0] and 5th largest element is 4.
Naive Approach: Generate all the possible products combination for each element in array arr[] with each element in array brr[]. Then sort the array of results and return the Kth element of the results array.
#include <bits/stdc++.h> using namespace std;
int solve( int a[ ], int n, int b[ ], int m, int k) {
vector< int > ans;
for ( int i = 0; i < n; i++) {
for ( int j = 0; j < m; j++) {
// take product
int prod = a[i] * b[j];
ans.push_back(prod);
}
}
// Sort array in descending order
sort(ans.begin(), ans.end(), greater< int >());
// Finally return (k - 1)th index
// as indexing begin from 0.
return ans[k - 1];
} // Driver code int main()
{ int arr[ ] = { 1, -2, 3 };
int brr[ ] = { 3, -4, 0 };
int K = 3;
int n = sizeof (arr) / sizeof ( int );
int m = sizeof (brr) / sizeof ( int );
// Function Call
int val = solve(arr, n, brr, m, K);
cout << val;
return 0;
} // This code is contributed by hrithikgarg03188 |
// Java code for the above approach import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
class GFG {
static int solve( int [] a, int [] b, int k) {
List<Integer> ans = new LinkedList<>();
int n = a.length;
int m = b.length;
for ( int i = 0 ; i < n; i++) {
for ( int j = 0 ; j < m; j++) {
// take product
int prod = a[i] * b[j];
ans.add(prod);
}
}
// Sort array in descending order
Collections.sort(ans, (x, y) -> y - x);
// Finally return (k - 1)th index
// as indexing begins from 0.
return (ans.get(k - 1 ));
}
// Driver Code
public static void main(String[] args)
{
int [] arr = { 1 , - 2 , 3 };
int [] brr = { 3 , - 4 , 0 };
int K = 3 ;
// Function Call
int val = solve(arr, brr, K);
System.out.println(val);
}
} // This code is contributed by 29AjayKumar |
# Python program for above approach def solve(a, b, k):
ans = []
n = len (a)
m = len (b)
for i in range (n):
for j in range (m):
# take product
prod = a[i] * b[j]
ans.append(prod)
# Sort array in descending order
ans.sort(reverse = True )
# Finally return (k-1)th index
# as indexing begins from 0.
return (ans[k - 1 ])
# Driver Code arr = [ 1 , - 2 , 3 ]
brr = [ 3 , - 4 , 0 ]
K = 3
# Function Call val = solve(arr, brr, K)
print (val)
|
// C# code for the above approach using System;
using System.Collections.Generic;
public class GFG {
static int solve( int [] a, int [] b, int k) {
List< int > ans = new List< int >();
int n = a.Length;
int m = b.Length;
for ( int i = 0; i < n; i++) {
for ( int j = 0; j < m; j++) {
// take product
int prod = a[i] * b[j];
ans.Add(prod);
}
}
// Sort array in descending order
ans.Sort((x, y) => y - x);
// Finally return (k - 1)th index
// as indexing begins from 0.
return (ans[k - 1]);
}
// Driver Code
public static void Main(String[] args)
{
int [] arr = { 1, -2, 3 };
int [] brr = { 3, -4, 0 };
int K = 3;
// Function Call
int val = solve(arr, brr, K);
Console.WriteLine(val);
}
} // This code is contributed by 29AjayKumar |
<script> // JavaScript code for the above approach
function solve(a, b, k)
{
ans = []
n = a.length
m = b.length
for (let i = 0; i < n; i++)
{
for (let j = 0; j < m; j++)
{
// take product
prod = a[i] * b[j]
ans.push(prod)
}
}
// Sort array in descending order
ans.sort( function (a, b) { return b - a })
// Finally return (k - 1)th index
// as indexing begins from 0.
return (ans[k - 1])
}
// Driver Code
arr = [1, -2, 3]
brr = [3, -4, 0]
K = 3
// Function Call
val = solve(arr, brr, K)
document.write(val)
// This code is contributed by Potta Lokesh </script>
|
3
Time Complexity: O(N*M + (N+M) * Log(N+M))
Auxiliary Space: O(N+M)
Efficient Approach: This problem can be solved by using the Greedy Approach and Heaps. Follow the steps below to solve the given problem.
- Sort the brr[] array.
- Keep larger size array in the array arr[].
- Create a max heap to store the elements with their respective indices.
- Traverse each element from array arr[]. The element can be either positive or negative.
- Positive: Multiply current element from arr[] with the largest element of sorted array brr[]. To ensure that maximum element is obtained.
- Negative: In this case multiply with the smallest value, i.e. with the first element from array brr[]. This is due to the property of negation, as a larger value can be obtained by multiplying with the smallest one.
- Insert three values into heap such that : ( product, i, j ) where i & j are the indices of arrays arr[] and brr[].
- Now run a for loop K times and pop elements from the heap.
- Now check if the value present at arr[i] is positive or negative
- Positive: So next_j = ( current_j – 1) because as max heap is been used, all the higher indices might have been already popped from the heap.
- Negative: next_j = (current_j +1) because all the smaller values yielding larger elements might have been already popped from the heap.
- Finally, return the answer
Note: Max heap is implemented with the help of min-heap, by negating the signs of the values while inserting them into the heap in Python.
Below is the implementation of the above approach.
// C++program for above approach #include<bits/stdc++.h> using namespace std;
class Pair {
public :
int val;
int i;
int j;
Pair( int val, int i, int j)
{
this ->val = val;
this ->i = i;
this ->j = j;
}
}; struct comparator {
bool operator()(Pair const & p1, Pair const & p2)
{
// return "true" if "p1" is ordered
// before "p2", for example:
return p1.val < p2.val;
}
}; int solve( int * a, int * b, int k)
{ // Sorting array b in ascending order
sort(b, b + k);
int n = k;
int m = k;
// Checking if size(a) > size(b)
if (n < m) {
// Otherwise swap the arrays
return solve(b, a, k);
}
// Create a max heap
priority_queue<Pair, vector<Pair>, comparator> heap;
// Traverse all elements in array a
for ( int i = 0; i < n; i++) {
int curr = a[i];
// curr element is negative
if (curr < 0) {
// Product with smallest value
int val = curr * b[0];
// Pushing the value and i as well jth index
heap.push(Pair(val, i, 0));
}
else
{
// Product with largest value
int val = curr * b[m - 1];
// Pushing the value and i as well jth index
heap.push(Pair(val, i, m - 1));
}
}
// Subtract 1 due to zero indexing
k--;
// Remove k-1 largest items from heap
for ( int i = 0; i < k; i++) {
Pair pair = heap.top();
heap.pop();
int val = pair.val;
int iIndex = pair.i;
int jIndex = pair.j;
// if a[i] is negative, increment ith index
int nextJ;
if (a[iIndex] < 0) {
nextJ = jIndex + 1;
}
else
{
// if a[i] is positive, decrement jth index
nextJ = jIndex - 1;
}
// if index is valid
if (nextJ >= 0 && nextJ < m) {
int newVal = a[iIndex] * b[nextJ];
// Pushing new_val in the heap
heap.push(Pair(newVal, iIndex, nextJ));
}
}
// Finally return first val in the heap
return heap.top().val;
} int main()
{ int arr[] = { 1, -2, 3 };
int brr[] = { 3, -4, 0 };
int K = 3;
// Function Call
int val = solve(arr, brr, K);
// Print the result
cout << val << endl;
return 0;
} // The code is contributed by Nidhi goel. |
// Java program for above approach import java.io.*;
import java.util.*;
class Pair {
int val;
int i;
int j;
public Pair( int val, int i, int j)
{
this .val = val;
this .i = i;
this .j = j;
}
} class GFG {
static int solve( int [] a, int [] b, int k)
{
// Sorting array b in ascending order
Arrays.sort(b);
int n = a.length;
int m = b.length;
// Checking if size(a) > size(b)
if (n < m) {
// Otherwise swap the arrays
return solve(b, a, k);
}
// Create a max heap
PriorityQueue<Pair> heap = new PriorityQueue<>(
(p1, p2) -> p2.val - p1.val);
// Traverse all elements in array a
for ( int i = 0 ; i < n; i++) {
int curr = a[i];
// curr element is negative
if (curr < 0 ) {
// Product with smallest value
int val = curr * b[ 0 ];
// Pushing the value and i as well jth index
heap.add( new Pair(val, i, 0 ));
}
else {
// Product with largest value
int val = curr * b[m - 1 ];
// Pushing the value and i as well jth index
heap.add( new Pair(val, i, m - 1 ));
}
}
// Subtract 1 due to zero indexing
k--;
// Remove k-1 largest items from heap
for ( int i = 0 ; i < k; i++) {
Pair pair = heap.poll();
int val = pair.val;
int iIndex = pair.i;
int jIndex = pair.j;
// if a[i] is negative, increment ith index
int nextJ;
if (a[iIndex] < 0 ) {
nextJ = jIndex + 1 ;
}
else {
// if a[i] is positive, decrement jth index
nextJ = jIndex - 1 ;
}
// if index is valid
if (nextJ >= 0 && nextJ < m) {
int newVal = a[iIndex] * b[nextJ];
// Pushing new_val in the heap
heap.add( new Pair(newVal, iIndex, nextJ));
}
}
// Finally return first val in the heap
return heap.peek().val;
}
public static void main(String[] args)
{
int [] arr = { 1 , - 2 , 3 };
int [] brr = { 3 , - 4 , 0 };
int K = 3 ;
// Function Call
int val = solve(arr, brr, K);
// Print the result
System.out.println(val);
}
} // This code is contributed by lokesh. |
# Python program for above approach from heap import heappush as push, heappop as pop
def solve(a, b, k):
# Sorting array b in ascending order
b.sort()
n, m = len (a), len (b)
# Checking if size(a) > size(b)
if (n < m):
# Otherwise swap the arrays
return solve(b, a, k)
heap = []
# Traverse all elements in array a
for i in range (n):
curr = a[i]
# curr element is negative
if (curr < 0 ):
# Product with smallest value
val = curr * b[ 0 ]
# Pushing negative val due to max heap
# and i as well jth index
push(heap, ( - val, i, 0 ))
else :
# Product with largest value
val = curr * b[ - 1 ]
# Pushing negative val due to max heap
# and i as well jth index
push(heap, ( - val, i, m - 1 ))
# Subtract 1 due to zero indexing
k = k - 1
# Remove k-1 largest items from heap
for _ in range (k):
val, i, j = pop(heap)
val = - val
# if a[i] is negative, increment ith index
if (a[i] < 0 ):
next_j = j + 1
# if a[i] is positive, decrement jth index
else :
next_j = j - 1
# if index is valid
if ( 0 < = next_j < m):
new_val = a[i] * b[next_j]
# Pushing new_val in the heap
push(heap, ( - new_val, i, next_j))
# Finally return first val in the heap
return - (heap[ 0 ][ 0 ])
# Driver Code arr = [ 1 , - 2 , 3 ]
brr = [ 3 , - 4 , 0 ]
K = 3
# Function Call val = solve(arr, brr, K)
# Print the result print (val)
|
// C# program for above approach using System;
using System.Collections.Generic;
class Pair : IComparable<Pair>
{ public int val;
public int i;
public int j;
public Pair( int val, int i, int j)
{
this .val = val;
this .i = i;
this .j = j;
}
public int CompareTo(Pair other)
{
return this .val - other.val;
}
} public class GFG
{ static int solve( int [] a, int [] b, int k)
{
// Sorting array b in ascending order
Array.Sort(b);
int n = a.Length;
int m = b.Length;
// Checking if size(a) > size(b)
if (n < m)
{
// Otherwise swap the arrays
return solve(b, a, k);
}
// Create a max heap
SortedSet<Pair> heap = new SortedSet<Pair>();
// Traverse all elements in array a
for ( int i = 0; i < n; i++)
{
int curr = a[i];
// curr element is negative
if (curr < 0)
{
// Product with smallest value
int val = curr * b[0];
// Pushing the value and i as well jth index
heap.Add( new Pair(val, i, 0));
}
else
{
// Product with largest value
int val = curr * b[m - 1];
// Pushing the value and i as well jth index
heap.Add( new Pair(val, i, m - 1));
}
}
// Subtract 1 due to zero indexing
k--;
// Remove k-1 largest items from heap
for ( int i = 0; i < k; i++)
{
Pair pair = heap.Max;
heap.Remove(pair);
int iIndex = pair.i;
int jIndex = pair.j;
// if a[i] is negative, increment ith index
int nextJ;
if (a[iIndex] < 0)
{
nextJ = jIndex + 1;
}
else
{
// if a[i] is positive, decrement jth index
nextJ = jIndex - 1;
}
// if index is valid
if (nextJ >= 0 && nextJ < m)
{
int newVal = a[iIndex] * b[nextJ];
// Pushing new_val in the heap
heap.Add( new Pair(newVal, iIndex, nextJ));
}
}
// Finally return first val in the heap
return heap.Max.val;
}
static void Main( string [] args)
{
int [] arr = { 1, -2, 3 };
int [] brr = { 3, -4, 0 };
int K = 3;
// Function Call
int val = solve(arr, brr, K);
// Print the result
Console.WriteLine(val);
}
} |
// Javascript program for above approach class Pair { constructor(val, i, j)
{
this .val = val;
this .i = i;
this .j = j;
}
} function sortFunction(a, b) {
return a[0] - b[0];
} function solve(a, b, k)
{ // Sorting array b in ascending order
b.sort();
let n = k;
let m = k;
// Checking if size(a) > size(b)
if (n < m) {
// Otherwise swap the arrays
return solve(b, a, k);
}
// Create a max heap
let heap = [];
// Traverse all elements in array a
for (let i = 0; i < n; i++) {
let curr = a[i];
// curr element is negative
if (curr < 0) {
// Product with smallest value
let val = curr * b[0];
// Pushing the value and i as well jth index
heap.push([val, i, 0]);
heap.sort(sortFunction);
}
else
{
// Product with largest value
let val = curr * b[m - 1];
// Pushing the value and i as well jth index
heap.push([val, i, m - 1]);
heap.sort(sortFunction);
}
}
// Subtract 1 due to zero indexing
k--;
// Remove k-1 largest items from heap
for (let i = 0; i < k; i++) {
let pair = heap[heap.length - 1];
heap.pop();
let val = pair[0];
let iIndex = pair[1];
let jIndex = pair[2];
// if a[i] is negative, increment ith index
let nextJ = 0;
if (a[iIndex] < 0) {
nextJ = jIndex + 1;
}
else
{
// if a[i] is positive, decrement jth index
nextJ = jIndex - 1;
}
// if index is valid
if (nextJ >= 0 && nextJ < m) {
let newVal = a[iIndex] * b[nextJ];
// Pushing new_val in the heap
heap.push([newVal, iIndex, nextJ]);
heap.sort(sortFunction);
}
}
// Finally return first val in the heap
return heap[heap.length - 1][0];
} let arr = [1, -2, 3]; let brr = [3, -4, 0]; let K = 3; // Function Call let val = solve(arr, brr, K); // Print the result console.log(val); // The code is contributed by Nidhi goel. |
3
Time Complexity: O(M*Log(M) + K*Log(N))
Auxiliary Space: O(N)