Find the Kth smallest element in the sorted generated array
Last Updated :
31 May, 2022
Given an array arr[] of N elements and an integer K, the task is to generate an B[] with the following rules:
- Copy elements arr[1…N], N times to array B[].
- Copy elements arr[1…N/2], 2*N times to array B[].
- Copy elements arr[1…N/4], 3*N times to array B[].
- 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:
- 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.
- Take cumulative sum of count array.
- Maintain all elements of arr[] with their count in Array B[] along with their counts and sort them based on element value.
- Traverse through vector and see which element has Kth position in B[] as per their individual counts.
- If K is out of bounds of B[] then return -1.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int solve( int Array[], int N, int K)
{
int count_Arr[N + 1] = { 0 };
int factor = 1;
int size = N;
while (size) {
int start = 1;
int end = size;
count_Arr[1] += factor * N;
count_Arr[end + 1] -= factor * N;
factor++;
size /= 2;
}
for ( int i = 2; i <= N; i++)
count_Arr[i] += count_Arr[i - 1];
vector<pair< int , int > > element;
for ( int i = 0; i < N; i++) {
element.push_back({ Array[i], count_Arr[i + 1] });
}
sort(element.begin(), element.end());
int start = 1;
for ( int i = 0; i < N; i++) {
int end = start + element[i].second - 1;
if (K >= start && K <= end) {
return element[i].first;
}
start += element[i].second;
}
return -1;
}
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;
}
|
Java
import java.util.Vector;
class GFG
{
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;
}
}
static int solve( int [] Array, int N, int K)
{
int [] count_Arr = new int [N + 2 ];
int factor = 1 ;
int size = N;
while (size > 0 )
{
int start = 1 ;
int end = size;
count_Arr[ 1 ] += factor * N;
count_Arr[end + 1 ] -= factor * N;
factor++;
size /= 2 ;
}
for ( int i = 2 ; i <= N; i++)
count_Arr[i] += count_Arr[i - 1 ];
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 (K >= start && K <= end)
return element.elementAt(i).getFirst();
start += element.elementAt(i).getSecond();
}
return - 1 ;
}
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));
}
}
|
Python3
def solve(Array, N, K) :
count_Arr = [ 0 ] * (N + 2 ) ;
factor = 1 ;
size = N;
while (size) :
start = 1 ;
end = size;
count_Arr[ 1 ] + = factor * N;
count_Arr[end + 1 ] - = factor * N;
factor + = 1 ;
size / / = 2 ;
for i in range ( 2 , N + 1 ) :
count_Arr[i] + = count_Arr[i - 1 ];
element = [];
for i in range (N) :
element.append(( Array[i], count_Arr[i + 1 ] ));
element.sort();
start = 1 ;
for i in range (N) :
end = start + element[i][ 1 ] - 1 ;
if (K > = start and K < = end) :
return element[i][ 0 ];
start + = element[i][ 1 ];
return - 1 ;
if __name__ = = "__main__" :
arr = [ 2 , 4 , 5 , 1 ];
N = len (arr);
K = 13 ;
print (solve(arr, N, K));
|
C#
using System;
using System.Collections.Generic;
class GFG
{
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;
}
}
static int solve( int [] Array, int N, int K)
{
int [] count_Arr = new int [N + 2];
int factor = 1;
int size = N;
while (size > 0)
{
int end = size;
count_Arr[1] += factor * N;
count_Arr[end + 1] -= factor * N;
factor++;
size /= 2;
}
for ( int i = 2; i <= N; i++)
count_Arr[i] += count_Arr[i - 1];
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 (K >= start && K <= end)
return element[i].getFirst();
start += element[i].getSecond();
}
return -1;
}
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));
}
}
|
Javascript
<script>
function solve(arr, N, K) {
let count_Arr = new Array(N + 1).fill(0);
let factor = 1;
let size = N;
while (size) {
let start = 1;
let end = size;
count_Arr[1] += factor * N;
count_Arr[end + 1] -= factor * N;
factor++;
size = Math.floor(size / 2);
}
for (let i = 2; i <= N; i++)
count_Arr[i] += count_Arr[i - 1];
let element = [];
for (let i = 0; i < N; i++) {
element.push([arr[i], count_Arr[i + 1]]);
}
element.sort((a, b) => a - b);
let start = 1;
for (let i = 0; i < N; i++) {
let end = start + element[i][1] - 1;
if (K >= start && K <= end) {
return element[i][0];
}
start += element[i][1];
}
return -1;
}
let arr = [2, 4, 5, 1];
let N = arr.length;
let K = 13;
document.write(solve(arr, N, K));
</script>
|
Time Complexity: O(N * log N)
Auxiliary Space: O(N)
Share your thoughts in the comments
Please Login to comment...