Find the Kth smallest element in the sorted generated array

Given an array arr[] of N elements and an integer K, the task is to generate an B[] with the following rules:

  1. Copy elements arr[1…N], N times to array B[].
  2. Copy elements arr[1…N/2], 2*N times to array B[].
  3. Copy elements arr[1…N/4], 3*N times to array B[].
  4. Similarly, until only no element is left to be copied to array B[].

Finally print the Kth smallest element from the array B[]. If K is out of bounds of B[] then return -1.

Examples:



Input: arr[] = {1, 2, 3}, K = 4
Output: 1
{1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 1, 1, 1, 1, 1} is the required array B[]
{1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3} in the sorted form where
1 is the 4th smallest element.

Input: arr[] = {2, 4, 5, 1}, K = 13
Output: 2

Approach:

  1. Maintain a Count_Array where we must store the count of times every element occurs in array B[]. It can be done for range of elements by adding the count at start index and subtracting the same count at end index + 1 location.
  2. Take cumulative sum of count array.
  3. Maintain all elements of arr[] with their count in Array B[] along with their counts and sort them based on element value.
  4. Traverse through vector and see which element has Kth position in B[] as per their individual counts.
  5. If K is out of bounds of B[] then return -1.

Below is the implementation of the above approach:

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
  
// Function to return the Kth element in B[]
int solve(int Array[], int N, int K)
{
  
    // Initialize the count Array
    int count_Arr[N + 1] = { 0 };
    int factor = 1;
    int size = N;
  
    // Reduce N repeatedly to half its value
    while (size) {
        int start = 1;
        int end = size;
  
        // Add count to start
        count_Arr[1] += factor * N;
  
        // Subtract same count after end index
        count_Arr[end + 1] -= factor * N;
        factor++;
        size /= 2;
    }
  
    for (int i = 2; i <= N; i++)
        count_Arr[i] += count_Arr[i - 1];
  
    // Store each element of Array[] with their count
    vector<pair<int, int> > element;
    for (int i = 0; i < N; i++) {
        element.push_back({ Array[i], count_Arr[i + 1] });
    }
  
    // Sort the elements wrt value
    sort(element.begin(), element.end());
  
    int start = 1;
    for (int i = 0; i < N; i++) {
        int end = start + element[i].second - 1;
  
        // If Kth element is in range of element[i]
        // return element[i]
        if (K >= start && K <= end) {
            return element[i].first;
        }
  
        start += element[i].second;
    }
  
    // If K is out of bound
    return -1;
}
  
// Driver code
int main()
{
    int arr[] = { 2, 4, 5, 1 };
    int N = sizeof(arr) / sizeof(arr[0]);
    int K = 13;
  
    cout << solve(arr, N, K);
  
    return 0;
}
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java implementation of the approach 
import java.util.Vector;
  
class GFG 
{
  
    // Pair class implementation to use Pair
    static class Pair
    {
        private int first;
        private int second;
  
        Pair(int first, int second) 
        {
            this.first = first;
            this.second = second;
        }
  
        public int getFirst() 
        {
            return first;
        }
  
        public int getSecond()
        {
            return second;
        }
    }
  
    // Function to return the Kth element in B[]
    static int solve(int[] Array, int N, int K)
    {
  
        // Initialize the count Array
        int[] count_Arr = new int[N + 2];
        int factor = 1;
        int size = N;
  
        // Reduce N repeatedly to half its value
        while (size > 0
        {
            int start = 1;
            int end = size;
  
            // Add count to start
            count_Arr[1] += factor * N;
  
            // Subtract same count after end index
            count_Arr[end + 1] -= factor * N;
            factor++;
            size /= 2;
        }
  
        for (int i = 2; i <= N; i++)
            count_Arr[i] += count_Arr[i - 1];
  
        // Store each element of Array[]
        // with their count
        Vector<Pair> element = new Vector<>();
        for (int i = 0; i < N; i++) 
        {
            Pair x = new Pair(Array[i], 
                              count_Arr[i + 1]);
            element.add(x);
        }
  
        int start = 1;
        for (int i = 0; i < N; i++) 
        {
            int end = start + element.elementAt(0).getSecond() - 1;
  
            // If Kth element is in range of element[i]
            // return element[i]
            if (K >= start && K <= end)
                return element.elementAt(i).getFirst();
  
            start += element.elementAt(i).getSecond();
        }
  
        // If K is out of bound
        return -1;
    }
  
    // Driver code
    public static void main(String[] args)
    {
        int[] arr = { 2, 4, 5, 1 };
        int N = arr.length;
        int K = 13;
        System.out.println(solve(arr, N, K));
    }
}    
  
// This code is contiributed by
// sanjeev2552
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 implementation of the approach 
  
# Function to return the Kth element in B[] 
def solve(Array, N, K) : 
  
    # Initialize the count Array 
    count_Arr = [0]*(N + 2) ; 
    factor = 1
    size = N; 
  
    # Reduce N repeatedly to half its value 
    while (size) :
        start = 1
        end = size; 
  
        # Add count to start 
        count_Arr[1] += factor * N; 
  
        # Subtract same count after end index 
        count_Arr[end + 1] -= factor * N; 
        factor += 1
        size //= 2
  
    for i in range(2, N + 1) : 
        count_Arr[i] += count_Arr[i - 1]; 
  
    # Store each element of Array[] with their count 
    element = [];
      
    for i in range(N) :
        element.append(( Array[i], count_Arr[i + 1] )); 
  
    # Sort the elements wrt value 
    element.sort(); 
  
    start = 1
    for i in range(N) :
        end = start + element[i][1] - 1
  
        # If Kth element is in range of element[i] 
        # return element[i] 
        if (K >= start and K <= end) :
            return element[i][0]; 
  
        start += element[i][1]; 
  
    # If K is out of bound 
    return -1
  
  
# Driver code 
if __name__ == "__main__"
  
    arr = [ 2, 4, 5, 1 ]; 
    N = len(arr); 
    K = 13
  
    print(solve(arr, N, K)); 
  
    # This code is contributed by AnkitRai01
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# implementation of the approach
using System;
using System.Collections.Generic;
      
class GFG 
{
  
    // Pair class implementation to use Pair
    public class Pair
    {
        public int first;
        public int second;
  
        public Pair(int first, int second) 
        {
            this.first = first;
            this.second = second;
        }
  
        public int getFirst() 
        {
            return first;
        }
  
        public int getSecond()
        {
            return second;
        }
    }
  
    // Function to return the Kth element in B[]
    static int solve(int[] Array, int N, int K)
    {
  
        // Initialize the count Array
        int[] count_Arr = new int[N + 2];
        int factor = 1;
        int size = N;
  
        // Reduce N repeatedly to half its value
        while (size > 0) 
        {
            int end = size;
  
            // Add count to start
            count_Arr[1] += factor * N;
  
            // Subtract same count after end index
            count_Arr[end + 1] -= factor * N;
            factor++;
            size /= 2;
        }
  
        for (int i = 2; i <= N; i++)
            count_Arr[i] += count_Arr[i - 1];
  
        // Store each element of Array[]
        // with their count
        List<Pair> element = new List<Pair>();
        for (int i = 0; i < N; i++) 
        {
            Pair x = new Pair(Array[i], 
                              count_Arr[i + 1]);
            element.Add(x);
        }
  
        int start = 1;
        for (int i = 0; i < N; i++) 
        {
            int end = start + element[0].getSecond() - 1;
  
            // If Kth element is in range of element[i]
            // return element[i]
            if (K >= start && K <= end)
                return element[i].getFirst();
  
            start += element[i].getSecond();
        }
  
        // If K is out of bound
        return -1;
    }
  
    // Driver code
    public static void Main(String[] args)
    {
        int[] arr = { 2, 4, 5, 1 };
        int N = arr.Length;
        int K = 13;
        Console.WriteLine(solve(arr, N, K));
    }
}
  
// This code is contributed by Rajput-Ji
chevron_right

Output:
2

GeeksforGeeks has prepared a complete interview preparation course with premium videos, theory, practice problems, TA support and many more features. Please refer Placement 100 for details





Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



Improved By : AnkitRai01, sanjeev2552, Rajput-Ji

Article Tags :
Practice Tags :