Open In App

Find the Kth smallest term in self cross-product Array

Last Updated : 16 Nov, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given an array arr[] of n elements, find the Kth lexicographically smallest in its corresponding cross-product array. For an array arr of n elements, the cross product of the array, cp_arr, is defined as cp_arr = {{arr[i], arr[j}} for all 0 < i, j < n.

Examples:

Input: n = 3, K = 7, arr[] = {3, 1, 2}
Output: [3, 1]
Explanation: [3, 1, 2] * [3, 1, 2] = [ [3, 3], [ 3, 1], [3, 2], [1, 3], [1, 1], [1, 2], [2, 3], [2, 1], [2, 2] ], now sort this cross product array to get the lexicographically increasing order. [[1, 1], [1, 2], [1, 3], [2, 1], [2, 2], [2, 3], [3, 1], [3, 2], [3, 3]] (in sorted order), so 7th is [3, 1]

Input: n = 4, K = 13, arr = {1, 7, 3, 1}
Output: [7, 1]
Explanation: [1, 7, 3, 1] * [1, 7, 3, 1] = [ [1, 1], [1, 7], [1, 3], [1, 1], [7, 1], [7, 7], [7, 3], [7, 1], [3, 1], [3, 7], [3, 3], [3, 1], [1, 1], [ 1, 7], [1, 3], [1, 1] ], now sort this cross product array to get the lexicographically increasing order. [[1, 1], [1, 1], [1, 1], [1, 1], [1, 3], [1, 3], [1, 7], [1, 7], [3, 1], [3, 1], [3, 3], [3, 7], [7, 1], [7, 1], [7, 3], [7, 7]] (in sorted order) so 13th element is [7, 1].

Approach: To solve the problem follow the below idea:

  • The approach is pretty simple we make an array which have all the unique integers array and also has a record of their frequencies and calculate how many pairs are there from each unique integer using their freq i.e. pairs with the first integer as x = freq[x]*n from the sorted array
    • If this count is > K value then find the second integer else subtract the number of pairs with x from K to get the correct first element
  • To get the second integer divide the leftover K by the freq of x and what even is left over that index element from the sorted array is the second element as we need to return the answer lexicographically, A bit more explanation is given if the freq is more than one repeated number of pairs will occur before proceeding to next integers so this value is calculated.

Follow the below steps to implement the above approach:

  • Make an array and put all unique numbers over there
  • Make an unordered_map to keep an check on frequency
  • Now iterate over the new array and check how to many pairs starting with current element lets call it temp
    • Subtract this number from temp from K till K>temp
  • Else proceed to find the second integer
  • To find the second integer divide left over K_count with freq of current element and find the index, then arr[index] is the output

Implementation of the above approach:

C++




// C++ code for the above approach:
#include <bits/stdc++.h>
#include <iostream>
using namespace std;
 
pair<int, int> func(int n, vector<int> arr, int k)
{
 
    // vector to store unique characters
    vector<int> b;
 
    b.reserve(n);
 
    // Frequency map
    unordered_map<int, long> freq;
 
    // Calculating freq and storing unique
    // numbers in b array
    for (int i = 0; i < n; i++) {
        if (!freq.count(arr[i])) {
            b.push_back(arr[i]);
        }
 
        freq[arr[i]]++;
    }
 
    // Sorting both the array's
 
    sort(b.begin(), b.end());
    sort(arr.begin(), arr.end());
 
    long long count = k;
    int x1, x2;
 
    int sz = b.size();
 
    for (int i = 0; i < sz; i++) {
 
        // Checking number of pair with each
        // number as first number
        long long temp = freq[b[i]] * n;
 
        // If we got the first number
        if (count <= temp) {
            x1 = b[i];
            long long temp1 = count;
 
            // Calculating second interger index
            long long hk = (temp1 / freq[b[i]])
                           - (temp1 % freq[b[i]] == 0);
            hk = max((long long)0, hk);
            x2 = arr[hk];
            break;
        }
 
        // Decresing count value
        else {
            count -= temp;
        }
    }
 
    return { x1, x2 };
}
 
// Drivers code
int main()
{
 
    vector<int> vec = { 3, 1, 2 };
    int n = vec.size();
    auto x = func(n, vec, 7);
 
    // Function Call
    cout << x.first << " " << x.second << endl;
 
    return 0;
}


Java




import java.util.*;
import java.util.AbstractMap.SimpleEntry;
 
public class Main {
     
    public static SimpleEntry<Integer, Integer> func(int n, List<Integer> arr, int k) {
        // ArrayList to store unique characters
        ArrayList<Integer> b = new ArrayList<>();
 
        // Frequency map
        HashMap<Integer, Long> freq = new HashMap<>();
 
        // Calculating frequency and storing unique
        // numbers in the 'b' array
        for (int i = 0; i < n; i++) {
            if (!freq.containsKey(arr.get(i))) {
                b.add(arr.get(i));
            }
 
            freq.put(arr.get(i), freq.getOrDefault(arr.get(i), 0L) + 1);
        }
 
        // Sorting both the arrays
        Collections.sort(b);
        Collections.sort(arr);
 
        long count = k;
        int x1 = 0, x2 = 0;
 
        int sz = b.size();
 
        for (int i = 0; i < sz; i++) {
            // Checking the number of pairs with each
            // number as the first number
            long temp = freq.get(b.get(i)) * n;
 
            // If we got the first number
            if (count <= temp) {
                x1 = b.get(i);
                long temp1 = count;
 
                // Calculating the index of the second integer
                long hk = (temp1 / freq.get(b.get(i))) - (temp1 % freq.get(b.get(i)) == 0 ? 1 : 0);
                hk = Math.max(0L, hk);
                x2 = arr.get((int) hk);
                break;
            }
 
            // Decreasing the count value
            else {
                count -= temp;
            }
        }
 
        return new SimpleEntry<>(x1, x2);
    }
 
    public static void main(String[] args) {
        List<Integer> vec = Arrays.asList(3, 1, 2);
        int n = vec.size();
        SimpleEntry<Integer, Integer> x = func(n, vec, 7);
 
        // Function Call
        System.out.println(x.getKey() + " " + x.getValue());
    }
}


Python




def func(n, arr, k):
    # List to store unique characters
    b = []
 
    # Frequency dictionary
    freq = {}
 
    # Calculate frequencies and store unique numbers in the 'b' list
    for i in range(n):
        if arr[i] not in freq:
            b.append(arr[i])
        freq[arr[i]] = freq.get(arr[i], 0) + 1
 
    # Sort both the lists
    b.sort()
    arr.sort()
 
    count = k
    x1, x2 = 0, 0
 
    sz = len(b)
 
    for i in range(sz):
        # Check the number of pairs with each number as the first number
        temp = freq[b[i]] * n
 
        # If we find the first number
        if count <= temp:
            x1 = b[i]
            temp1 = count
 
            # Calculate the index of the second integer
            hk = temp1 // freq[b[i]] - (temp1 % freq[b[i]] == 0)
            hk = max(0, hk)
            x2 = arr[hk]
            break
 
        # Decrease the count value
        else:
            count -= temp
 
    return (x1, x2)
 
# Driver code
vec = [3, 1, 2]
n = len(vec)
x = func(n, vec, 7)
 
# Function call
print(x[0], x[1])


C#




using System;
using System.Collections.Generic;
using System.Linq;
 
class Program
{
    static Tuple<int, int> Func(int n, List<int> arr, int k)
    {
        // List to store unique characters
        List<int> b = new List<int>();
 
        // Frequency dictionary
        Dictionary<int, int> freq = new Dictionary<int, int>();
 
        // Calculate frequencies and store unique numbers in the 'b' list
        for (int i = 0; i < n; i++)
        {
            if (!freq.ContainsKey(arr[i]))
            {
                b.Add(arr[i]);
            }
            freq[arr[i]] = freq.ContainsKey(arr[i]) ? freq[arr[i]] + 1 : 1;
        }
 
        // Sort both the lists
        b.Sort();
        arr.Sort();
 
        int count = k;
        int x1 = 0, x2 = 0;
 
        int sz = b.Count;
 
        for (int i = 0; i < sz; i++)
        {
            // Check the number of pairs with each number as the first number
            int temp = freq[b[i]] * n;
 
            // If we find the first number
            if (count <= temp)
            {
                x1 = b[i];
                int temp1 = count;
 
                // Calculate the index of the second integer
                int hk = temp1 / freq[b[i]] - (temp1 % freq[b[i]] == 0 ? 1 : 0);
                hk = Math.Max(0, hk);
                x2 = arr[hk];
                break;
            }
            // Decrease the count value
            else
            {
                count -= temp;
            }
        }
 
        return new Tuple<int, int>(x1, x2);
    }
 
    static void Main()
    {
        List<int> vec = new List<int> { 3, 1, 2 };
        int n = vec.Count;
        Tuple<int, int> x = Func(n, vec, 7);
 
        // Function call
        Console.WriteLine(x.Item1 + " " + x.Item2);
    }
}


Javascript




// JavaScript code for the above approach:
 
// Function to find a pair of integers in an array
// whose product is the k-th smallest product
function findPair(n, arr, k) {
    // Vector to store unique characters
    let b = [];
 
    // Frequency map
    let freq = new Map();
 
    // Calculating frequency and storing unique
    // numbers in the b array
    for (let i = 0; i < n; i++) {
        if (!freq.has(arr[i])) {
            b.push(arr[i]);
        }
 
        freq.set(arr[i], (freq.get(arr[i]) || 0) + 1);
    }
 
    // Sorting both the arrays
    b.sort((a, b) => a - b);
    arr.sort((a, b) => a - b);
 
    let count = k;
    let x1, x2;
 
    let sz = b.length;
 
    for (let i = 0; i < sz; i++) {
        // Checking the number of pairs with each
        // number as the first number
        let temp = freq.get(b[i]) * n;
 
        // If we found the first number
        if (count <= temp) {
            x1 = b[i];
            let temp1 = count;
 
            // Calculating the index of the second integer
            let hk = Math.floor(temp1 / freq.get(b[i])) - (temp1 % freq.get(b[i]) === 0 ? 1 : 0);
            hk = Math.max(0, hk);
            x2 = arr[hk];
            break;
        }
 
        // Decreasing the count value
        else {
            count -= temp;
        }
    }
 
    return [x1, x2];
}
 
// Driver code
let vec = [3, 1, 2];
let n = vec.length;
let x = findPair(n, vec, 7);
 
// Function call
console.log(x[0], x[1]);


Output

3 1









Time Complexity: O(N)
Auxiliary Space: O(N)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads