Given a sorted array arr[] of size N and an integer K, the task is to find Kth smallest element present in the array. The given array has been obtained by reversing subarrays {arr[0], arr[R]} and {arr[R + 1], arr[N – 1]} at some random index R. If the key is not present in the array, print -1.
Examples:
Input: arr[] = { 4, 3, 2, 1, 8, 7, 6, 5 }, K = 2
Output: 2
Explanation: Sorted form of the array arr[] is { 1, 2, 3, 4, 5, 6, 7, 8 }. Therefore, the 2nd smallest element in the array arr[] is 2.
Input: arr[] = { 10, 8, 6, 5, 2, 1, 13, 12 }, K = 3
Output: 5
Naive Approach: The simplest approach to solve the problem is to sort the given array arr[] in increasing order and print the Kth smallest element in the array.
Time Complexity: O(N*log(N))
Auxiliary Space: O(1)
Alternative approach of the above solution: We can sort the array without using any sorting technique which will surely reduce the time complexity. We can just find the pivot point P in the array(around which the rotation occurs) using binary search and just reverse the two subarrays [0, P + 1] and [P + 1, N] using std::reverse() function in C++.
Reversing the subarrays: After finding the pivot point P, just find the reverse of the two subarrays as following:
std::reverse(arr, arr + P + 1);
std::reverse(arr + P + 1, arr + N);
And thus we get the sorted array and we can print the Kth smallest element as arr[K-1].
C++
#include <bits/stdc++.h>
using namespace std;
int findPivot( int arr[], int low, int high)
{
if (high < low)
return -1;
if (high == low)
return low;
int mid = (low + high) / 2;
if (mid < high && arr[mid] < arr[mid + 1])
return mid;
if (mid > low && arr[mid] > arr[mid - 1])
return (mid - 1);
if (arr[low] <= arr[mid])
return findPivot(arr, low, mid - 1);
return findPivot(arr, mid + 1, high);
}
int main()
{
int arr[] = { 10, 8, 6, 5, 2, 1, 13, 12 };
int N = sizeof (arr) / sizeof (arr[0]);
int K = 3;
int P = findPivot(arr, 0, N - 1);
reverse(arr, arr + P + 1);
reverse(arr + P + 1, arr + N);
cout << arr[K - 1];
return 0;
}
|
Java
import java.util.*;
class GFG{
static int findPivot( int arr[], int low, int high)
{
if (high < low)
return - 1 ;
if (high == low)
return low;
int mid = (low + high) / 2 ;
if (mid < high && arr[mid] < arr[mid + 1 ])
return mid;
if (mid > low && arr[mid] > arr[mid - 1 ])
return (mid - 1 );
if (arr[low] <= arr[mid])
return findPivot(arr, low, mid - 1 );
return findPivot(arr, mid + 1 , high);
}
static void reverse( int str[], int start, int end)
{
int temp;
while (start <= end)
{
temp = str[start];
str[start] = str[end];
str[end] = temp;
start++;
end--;
}
}
public static void main(String[] args)
{
int arr[] = { 10 , 8 , 6 , 5 , 2 , 1 , 13 , 12 };
int N = arr.length;
int K = 3 ;
int P = findPivot(arr, 0 , N - 1 );
reverse(arr, 0 , P);
reverse(arr, P, N - 1 );
System.out.print(arr[K - 1 ]);
}
}
|
Python3
def findPivot(arr, low, high):
if (high < low):
return - 1
if (high = = low):
return low
mid = int ((low + high) / 2 )
if (mid < high and arr[mid] < arr[mid + 1 ]):
return mid
if (mid > low and arr[mid] > arr[mid - 1 ]):
return (mid - 1 )
if (arr[low] < = arr[mid]):
return findPivot(arr, low, mid - 1 )
return findPivot(arr, mid + 1 , high)
def reverse( Str , start, end):
while (start < = end):
temp = Str [start]
Str [start] = Str [end]
Str [end] = temp
start + = 1
end - = 1
arr = [ 10 , 8 , 6 , 5 , 2 , 1 , 13 , 12 ]
N = len (arr)
K = 3
P = findPivot(arr, 0 , N - 1 )
reverse(arr, 0 , P)
reverse(arr, P, N - 1 )
print (arr[K - 1 ])
|
C#
using System;
class GFG {
static int findPivot( int [] arr, int low, int high)
{
if (high < low)
return -1;
if (high == low)
return low;
int mid = (low + high) / 2;
if (mid < high && arr[mid] < arr[mid + 1])
return mid;
if (mid > low && arr[mid] > arr[mid - 1])
return (mid - 1);
if (arr[low] <= arr[mid])
return findPivot(arr, low, mid - 1);
return findPivot(arr, mid + 1, high);
}
static void reverse( int [] str, int start, int end)
{
int temp;
while (start <= end)
{
temp = str[start];
str[start] = str[end];
str[end] = temp;
start++;
end--;
}
}
static void Main() {
int [] arr = { 10, 8, 6, 5, 2, 1, 13, 12 };
int N = arr.Length;
int K = 3;
int P = findPivot(arr, 0, N - 1);
reverse(arr, 0, P);
reverse(arr, P, N - 1);
Console.Write(arr[K - 1]);
}
}
|
Javascript
<script>
function findPivot(arr, low, high)
{
if (high < low)
return -1;
if (high == low)
return low;
let mid = parseInt((low + high) / 2, 10);
if (mid < high && arr[mid] < arr[mid + 1])
return mid;
if (mid > low && arr[mid] > arr[mid - 1])
return (mid - 1);
if (arr[low] <= arr[mid])
return findPivot(arr, low, mid - 1);
return findPivot(arr, mid + 1, high);
}
function reverse(i, j, arr)
{
let y = j - 1;
for (let x = i; x < j; x++)
{
arr[x] = arr[y];
y--;
}
}
let arr = [ 10, 8, 6, 5, 2, 1, 13, 12 ];
let N = arr.length;
let K = 3;
let P = findPivot(arr, 0, N - 1);
reverse(0, P + 1, arr);
reverse(P + 1, N, arr);
document.write(arr[K - 1]);
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(1)
Efficient Approach: The optimal idea is based on the observation that the Rth element is the smallest element because the elements in the range [1, R] are reversed. Now, if the random index is R, it means subarray [1, R] and [R + 1, N] are sorted in decreasing order. Therefore, the task reduceS to finding the value of R which can be obtained using binary search. Finally, print the Kth smallest element.
Follow the steps below to solve the problem:
- Initialize l as 1 and h as N to store the boundary elements index of the search space for the binary search.
- Loop while the value of l+1 < h
- Store the middle element in a variable, mid as (l+h)/2.
- If arr[l] ≥ arr[mid]. If it is true then check on the right side of mid by updating l to mid.
- Otherwise, update r to mid.
- Now after finding R, if K ≤ R, then the answer is arr[R-K+1]. Otherwise, arr[N-(K-R)+1].
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int findkthElement(vector< int > arr, int n, int K)
{
int l = 0;
int h = n - 1, r;
while (l + 1 < h)
{
int mid = (l + h) / 2;
if (arr[l] >= arr[mid])
l = mid;
else
h = mid;
}
if (arr[l] < arr[h])
r = l;
else
r = h;
if (K <= r + 1)
return arr[r + 1 - K];
else
return arr[n - (K - (r + 1))];
}
int main()
{
vector< int > arr = { 10, 8, 6, 5, 2, 1, 13, 12 };
int n = arr.size();
int K = 3;
cout << findkthElement(arr, n, K);
}
|
Java
class GFG{
public static int findkthElement( int arr[], int n, int K)
{
int l = 0 ;
int h = n - 1 , r;
while (l + 1 < h)
{
int mid = (l + h) / 2 ;
if (arr[l] >= arr[mid])
l = mid;
else
h = mid;
}
if (arr[l] < arr[h])
r = l;
else
r = h;
if (K <= r + 1 )
return arr[r + 1 - K];
else
return arr[n - (K - (r + 1 ))];
}
public static void main(String args[])
{
int []arr = { 10 , 8 , 6 , 5 , 2 , 1 , 13 , 12 };
int n = arr.length;
int K = 3 ;
System.out.println(findkthElement(arr, n, K));
}
}
|
Python3
def findkthElement(arr, n, K):
l = 0
h = n - 1
while l + 1 < h:
mid = (l + h) / / 2
if arr[l] > = arr[mid]:
l = mid
else :
h = mid
if arr[l] < arr[h]:
r = l
else :
r = h
if K < = r + 1 :
return arr[r + 1 - K]
else :
return arr[n - (K - (r + 1 ))]
if __name__ = = "__main__" :
arr = [ 10 , 8 , 6 , 5 , 2 , 1 , 13 , 12 ]
n = len (arr)
K = 3
print (findkthElement(arr, n, K) )
|
C#
using System.IO;
using System;
class GFG {
public static int findkthElement( int [] arr, int n,
int K)
{
int l = 0;
int h = n - 1, r;
while (l + 1 < h) {
int mid = (l + h) / 2;
if (arr[l] >= arr[mid])
l = mid;
else
h = mid;
}
if (arr[l] < arr[h])
r = l;
else
r = h;
if (K <= r + 1)
return arr[r + 1 - K];
else
return arr[n - (K - (r + 1))];
}
static void Main()
{
int [] arr = { 10, 8, 6, 5, 2, 1, 13, 12 };
int n = arr.Length;
int K = 3;
Console.WriteLine(findkthElement(arr, n, K));
}
}
|
Javascript
<script>
function findkthElement(arr, n, K) {
var l = 0;
var h = n - 1,
r;
while (l + 1 < h) {
var mid = parseInt((l + h) / 2);
if (arr[l] >= arr[mid]) l = mid;
else h = mid;
}
if (arr[l] < arr[h]) r = l;
else r = h;
if (K <= r + 1) return arr[r + 1 - K];
else return arr[n - (K - (r + 1))];
}
var arr = [10, 8, 6, 5, 2, 1, 13, 12];
var n = arr.length;
var K = 3;
document.write(findkthElement(arr, n, K));
</script>
|
Time Complexity: O(log(N))
Auxiliary Space: O(1)
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 :
07 Sep, 2021
Like Article
Save Article