Kth Smallest Element in a sorted array formed by reversing subarrays from a random index
Last Updated :
07 Sep, 2021
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)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...