Prerequisite: K’th Smallest/Largest Element in Unsorted Array | Set 1
Given an array and a number k where k is smaller than the size of the array, we need to find the k’th smallest element in the given array. It is given that all array elements are distinct.
Examples:
Input: arr[] = {7, 10, 4, 3, 20, 15}
k = 3
Output: 7
Input: arr[] = {7, 10, 4, 3, 20, 15}
k = 4
Output: 10
We have discussed three different solutions here.
Approach 1:
- Select a random element from an array as a pivot.
- Then partition to the array around the pivot, its help to all the smaller elements were placed before the pivot and all greater elements are placed after the pivot.
- then Check the position of the pivot. If it is the kth element then return it.
- If it is less than the kth element then repeat the process of the subarray.
- If it is greater than the kth element then repeat the process of the left subarray.
That Algorithm is the QuickSelect and It is similar to the QuickSort.
In this post method 5 is discussed which is mainly an extension of method 5 (QuickSelect) discussed in the previous post. The idea is to randomly pick a pivot element. To implement a randomized partition, we use a random function, rand() to generate an index between l and r, swap the element at the randomly generated index with the last element, and finally call the standard partition process which uses the last element as pivot.
Steps to solve the problem:
1. Check if k>0&& k<=r-l+1:
declare pos as randomPartition(arr,l,r).
check if pos-1==k-1 than return arr[pos].
check if pos-1>k-1 than recursively call kthsmallest(arr,l,pos-1,k).
return recursively call kthsmallest(arr,pos+1,r,k-pos+l-1).
2. Return INT_MAX.
Following is an implementation of the above Randomized QuickSelect.
C++
#include<iostream>
#include<climits>
#include<cstdlib>
using namespace std;
int randomPartition( int arr[], int l, int r);
int kthSmallest( int arr[], int l, int r, int k)
{
if (k > 0 && k <= r - l + 1)
{
int pos = randomPartition(arr, l, r);
if (pos-l == k-1)
return arr[pos];
if (pos-l > k-1)
return kthSmallest(arr, l, pos-1, k);
return kthSmallest(arr, pos+1, r, k-pos+l-1);
}
return INT_MAX;
}
void swap( int *a, int *b)
{
int temp = *a;
*a = *b;
*b = temp;
}
int partition( int arr[], int l, int r)
{
int x = arr[r], i = l;
for ( int j = l; j <= r - 1; j++)
{
if (arr[j] <= x)
{
swap(&arr[i], &arr[j]);
i++;
}
}
swap(&arr[i], &arr[r]);
return i;
}
int randomPartition( int arr[], int l, int r)
{
int n = r-l+1;
int pivot = rand () % n;
swap(&arr[l + pivot], &arr[r]);
return partition(arr, l, r);
}
int main()
{
int arr[] = {12, 3, 5, 7, 4, 19, 26};
int n = sizeof (arr)/ sizeof (arr[0]), k = 3;
cout << "K'th smallest element is " << kthSmallest(arr, 0, n-1, k);
return 0;
}
|
Java
class KthSmallst
{
int kthSmallest( int arr[], int l, int r, int k)
{
if (k > 0 && k <= r - l + 1 )
{
int pos = randomPartition(arr, l, r);
if (pos-l == k- 1 )
return arr[pos];
if (pos-l > k- 1 )
return kthSmallest(arr, l, pos- 1 , k);
return kthSmallest(arr, pos+ 1 , r, k-pos+l- 1 );
}
return Integer.MAX_VALUE;
}
void swap( int arr[], int i, int j)
{
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
int partition( int arr[], int l, int r)
{
int x = arr[r], i = l;
for ( int j = l; j < r; j++)
{
if (arr[j] <= x)
{
swap(arr, i, j);
i++;
}
}
swap(arr, i, r);
return i;
}
int randomPartition( int arr[], int l, int r)
{
int n = r - l + 1 ;
int pivot = ( int )(Math.random() * (n - 1 ));
swap(arr, l + pivot, r);
return partition(arr, l, r);
}
public static void main(String args[])
{
KthSmallst ob = new KthSmallst();
int arr[] = { 12 , 3 , 5 , 7 , 4 , 19 , 26 };
int n = arr.length,k = 3 ;
System.out.println( "K'th smallest element is " +
ob.kthSmallest(arr, 0 , n- 1 , k));
}
}
|
Python3
import random
def kthSmallest(arr, l, r, k):
if (k > 0 and k < = r - l + 1 ):
pos = randomPartition(arr, l, r)
if (pos - l = = k - 1 ):
return arr[pos]
if (pos - l > k - 1 ):
return kthSmallest(arr, l, pos - 1 , k)
return kthSmallest(arr, pos + 1 , r,
k - pos + l - 1 )
return 999999999999
def swap(arr, a, b):
temp = arr[a]
arr[a] = arr[b]
arr[b] = temp
def partition(arr, l, r):
x = arr[r]
i = l
for j in range (l, r):
if (arr[j] < = x):
swap(arr, i, j)
i + = 1
swap(arr, i, r)
return i
def randomPartition(arr, l, r):
n = r - l + 1
pivot = int (random.random() * n)
swap(arr, l + pivot, r)
return partition(arr, l, r)
if __name__ = = '__main__' :
arr = [ 12 , 3 , 5 , 7 , 4 , 19 , 26 ]
n = len (arr)
k = 3
print ( "K'th smallest element is" ,
kthSmallest(arr, 0 , n - 1 , k))
|
C#
using System;
class GFG
{
int kthSmallest( int []arr, int l, int r, int k)
{
if (k > 0 && k <= r - l + 1)
{
int pos = randomPartition(arr, l, r);
if (pos-l == k - 1)
return arr[pos];
if (pos - l > k - 1)
return kthSmallest(arr, l, pos - 1, k);
return kthSmallest(arr, pos + 1, r,
k - pos + l - 1);
}
return int .MaxValue;
}
void swap( int []arr, int i, int j)
{
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
int partition( int []arr, int l, int r)
{
int x = arr[r], i = l;
for ( int j = l; j <= r - 1; j++)
{
if (arr[j] <= x)
{
swap(arr, i, j);
i++;
}
}
swap(arr, i, r);
return i;
}
int randomPartition( int []arr, int l, int r)
{
int n = r - l + 1;
Random rnd = new Random();
int rand = rnd.Next(0, 1);
int pivot = ( int )(rand * (n - 1));
swap(arr, l + pivot, r);
return partition(arr, l, r);
}
public static void Main()
{
GFG ob = new GFG();
int []arr = {12, 3, 5, 7, 4, 19, 26};
int n = arr.Length,k = 3;
Console.Write( "K'th smallest element is " +
ob.kthSmallest(arr, 0, n - 1, k));
}
}
|
PHP
<?php
function kthSmallest( $arr , $l , $r , $k )
{
if ( $k > 0 && $k <= $r - $l + 1)
{
$pos = randomPartition( $arr , $l , $r );
if ( $pos - $l == $k -1)
return $arr [ $pos ];
if ( $pos - $l > $k -1)
return kthSmallest( $arr , $l , $pos -1, $k );
return kthSmallest( $arr , $pos +1, $r ,
$k - $pos + $l -1);
}
return PHP_INT_MAX;
}
function swap( $a , $b )
{
$temp = $a ;
$a = $b ;
$b = $temp ;
}
function partition( $arr , $l , $r )
{
$x = $arr [ $r ];
$i = $l ;
for ( $j = $l ; $j <= $r - 1; $j ++)
{
if ( $arr [ $j ] <= $x )
{
list( $arr [ $i ], $arr [ $j ])= array ( $arr [ $j ], $arr [ $i ]);
$i ++;
}
}
list( $arr [ $i ], $arr [ $r ])= array ( $arr [ $r ], $arr [ $i ]);
return $i ;
}
function randomPartition( $arr , $l , $r )
{
$n = $r - $l +1;
$pivot = rand() % $n ;
list( $arr [ $l + $pivot ], $arr [ $r ]) =
array ( $arr [ $r ], $arr [ $l + $pivot ] );
return partition( $arr , $l , $r );
}
$arr = array (12, 3, 5, 7, 4, 19, 260);
$n = sizeof( $arr )/sizeof( $arr [0]);
$k = 3;
echo "K'th smallest element is " ,
kthSmallest( $arr , 0, $n -1, $k );
?>
|
Javascript
<script>
function kthSmallest(arr,l,r,k)
{
if (k > 0 && k <= r - l + 1)
{
let pos = randomPartition(arr, l, r);
if (pos-l == k-1)
return arr[pos];
if (pos-l > k-1)
return kthSmallest(arr, l, pos-1, k);
return kthSmallest(arr, pos+1, r, k-pos+l-1);
}
return Integer.MAX_VALUE;
}
function swap(arr,i,j)
{
let temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
function partition(arr,l,r)
{
let x = arr[r], i = l;
for (let j = l; j <= r - 1; j++)
{
if (arr[j] <= x)
{
swap(arr, i, j);
i++;
}
}
swap(arr, i, r);
return i;
}
function randomPartition(arr,l,r)
{
let n = r-l+1;
let pivot = Math.floor((Math.random()) * (n-1));
swap(arr, l + pivot, r);
return partition(arr, l, r);
}
let arr=[12, 3, 5, 7, 4, 19, 26];
let n = arr.length,k = 3;
document.write( "K'th smallest element is " +
kthSmallest(arr, 0, n-1, k));
</script>
|
Output
K'th smallest element is 5
Time Complexity: O(n^2)
The worst-case time complexity of the above solution is still O(n2). In the worst case, the randomized function may always pick a corner element. The expected time complexity of the above randomized QuickSelect is O(n). The assumption in the analysis is, random number generator is equally likely to generate any number in the input range.
Auxiliary Space: O(1) since using constant variables.
Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!
Last Updated :
18 Sep, 2023
Like Article
Save Article