Given a sorted and rotated array arr[] of size N and a key, the task is to find the key in the array.
Note: Find the element in O(logN) time and assume that all the elements are distinct.
Example:
Input : arr[] = {5, 6, 7, 8, 9, 10, 1, 2, 3}, key = 3
Output : Found at index 8
Input : arr[] = {5, 6, 7, 8, 9, 10, 1, 2, 3}, key = 30
Output : Not found
Input : arr[] = {30, 40, 50, 10, 20}, key = 10
Output : Found at index 3
Approach 1 (Finding Pivot where rotation has happened): The primary idea to solve the problem is as follows.
The idea is to find the pivot point, divide the array into two sub-arrays and perform a binary search.
The main idea for finding a pivot is –
- For a sorted (in increasing order) and rotated array, the pivot element is the only element for which the next element to it is smaller than it.
- Using binary search based on the above idea, pivot can be found.
- It can be observed that for a search space of indices in range [l, r] where the middle index is mid,
- If rotation has happened in the left half, then obviously the element at l will be greater than the one at mid.
- Otherwise the left half will be sorted but the element at mid will be greater than the one at r.
- After the pivot is found divide the array into two sub-arrays.
- Now the individual sub-arrays are sorted so the element can be searched using Binary Search.
Follow the steps mentioned below to implement the idea:
- Find out the pivot point using binary search. We will set the low pointer as the first array index and high with the last array index.
- From the high and low we will calculate the mid value.
- If the value at mid-1 is greater than the one at mid, return that value as the pivot.
- Else if the value at the mid+1 is less than mid, return mid value as the pivot.
- Otherwise, if the value at low position is greater than mid position, consider the left half. Otherwise, consider the right half.
- Divide the array into two sub-arrays based on the pivot that was found.
- Now call binary search for one of the two sub-arrays.
- If the element is greater than the 0th element then search in the left array
- Else search in the right array.
- If the element is found in the selected sub-array then return the index
- Else return -1.
Follow the below illustration for a better understanding
Illustration:
Consider arr[] = {3, 4, 5, 1, 2}, key = 1
Pivot finding:
low = 0, high = 4:
=> mid = 2
=> arr[mid] = 5, arr[mid + 1] = 1
=> arr[mid] > arr[mid +1],
=> Therefore the pivot = mid = 2
Array is divided into two parts {3, 4, 5}, {1, 2}
Now according to the conditions and the key, we need to find in the part {1, 2}
Key Finding:
We will apply Binary search on {1, 2}.
low = 3 , high = 4.
=> mid = 3
=> arr[mid] = 1 , key = 1, hence arr[mid] = key matches.
=> The required index = mid = 3
So the element is found at index 3.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int binarySearch( int arr[], int low, int high, int key)
{
if (high < low)
return -1;
int mid = (low + high) / 2;
if (key == arr[mid])
return mid;
if (key > arr[mid])
return binarySearch(arr, (mid + 1), high, key);
return binarySearch(arr, low, (mid - 1), key);
}
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 pivotedBinarySearch( int arr[], int n, int key)
{
int pivot = findPivot(arr, 0, n - 1);
if (pivot == -1)
return binarySearch(arr, 0, n - 1, key);
if (arr[pivot] == key)
return pivot;
if (arr[0] <= key)
return binarySearch(arr, 0, pivot - 1, key);
return binarySearch(arr, pivot + 1, n - 1, key);
}
int main()
{
int arr1[] = { 5, 6, 7, 8, 9, 10, 1, 2, 3 };
int n = sizeof (arr1) / sizeof (arr1[0]);
int key = 3;
cout << "Index of the element is : "
<< pivotedBinarySearch(arr1, n, key);
return 0;
}
|
C
#include <stdio.h>
int findPivot( int [], int , int );
int binarySearch( int [], int , int , int );
int pivotedBinarySearch( int arr[], int n, int key)
{
int pivot = findPivot(arr, 0, n - 1);
if (pivot == -1)
return binarySearch(arr, 0, n - 1, key);
if (arr[pivot] == key)
return pivot;
if (arr[0] <= key)
return binarySearch(arr, 0, pivot - 1, key);
return binarySearch(arr, pivot + 1, n - 1, key);
}
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 binarySearch( int arr[], int low, int high, int key)
{
if (high < low)
return -1;
int mid = (low + high) / 2;
if (key == arr[mid])
return mid;
if (key > arr[mid])
return binarySearch(arr, (mid + 1), high, key);
return binarySearch(arr, low, (mid - 1), key);
}
int main()
{
int arr1[] = { 5, 6, 7, 8, 9, 10, 1, 2, 3 };
int n = sizeof (arr1) / sizeof (arr1[0]);
int key = 3;
printf ( "Index of the element is : %d" ,
pivotedBinarySearch(arr1, n, key));
return 0;
}
|
Java
import java.io.*;
class Main {
static int pivotedBinarySearch( int arr[], int n,
int key)
{
int pivot = findPivot(arr, 0 , n - 1 );
if (pivot == - 1 )
return binarySearch(arr, 0 , n - 1 , key);
if (arr[pivot] == key)
return pivot;
if (arr[ 0 ] <= key)
return binarySearch(arr, 0 , pivot - 1 , key);
return binarySearch(arr, pivot + 1 , n - 1 , key);
}
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 int binarySearch( int arr[], int low, int high,
int key)
{
if (high < low)
return - 1 ;
int mid = (low + high) / 2 ;
if (key == arr[mid])
return mid;
if (key > arr[mid])
return binarySearch(arr, (mid + 1 ), high, key);
return binarySearch(arr, low, (mid - 1 ), key);
}
public static void main(String args[])
{
int arr1[] = { 5 , 6 , 7 , 8 , 9 , 10 , 1 , 2 , 3 };
int n = arr1.length;
int key = 3 ;
System.out.println(
"Index of the element is : "
+ pivotedBinarySearch(arr1, n, key));
}
}
|
Python3
def pivotedBinarySearch(arr, n, key):
pivot = findPivot(arr, 0 , n - 1 )
if pivot = = - 1 :
return binarySearch(arr, 0 , n - 1 , key)
if arr[pivot] = = key:
return pivot
if arr[ 0 ] < = key:
return binarySearch(arr, 0 , pivot - 1 , key)
return binarySearch(arr, pivot + 1 , n - 1 , key)
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 binarySearch(arr, low, high, key):
if high < low:
return - 1
mid = int ((low + high) / 2 )
if key = = arr[mid]:
return mid
if key > arr[mid]:
return binarySearch(arr, (mid + 1 ), high,
key)
return binarySearch(arr, low, (mid - 1 ), key)
if __name__ = = '__main__' :
arr1 = [ 5 , 6 , 7 , 8 , 9 , 10 , 1 , 2 , 3 ]
n = len (arr1)
key = 3
print ( "Index of the element is : " , \
pivotedBinarySearch(arr1, n, key))
|
C#
using System;
class main {
static int pivotedBinarySearch( int [] arr,
int n, int key)
{
int pivot = findPivot(arr, 0, n - 1);
if (pivot == -1)
return binarySearch(arr, 0, n - 1, key);
if (arr[pivot] == key)
return pivot;
if (arr[0] <= key)
return binarySearch(arr, 0, pivot - 1, key);
return binarySearch(arr, pivot + 1, n - 1, key);
}
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 int binarySearch( int [] arr, int low,
int high, int key)
{
if (high < low)
return -1;
int mid = (low + high) / 2;
if (key == arr[mid])
return mid;
if (key > arr[mid])
return binarySearch(arr, (mid + 1), high, key);
return binarySearch(arr, low, (mid - 1), key);
}
public static void Main()
{
int [] arr1 = { 5, 6, 7, 8, 9, 10, 1, 2, 3 };
int n = arr1.Length;
int key = 3;
Console.Write( "Index of the element is : "
+ pivotedBinarySearch(arr1, n, key));
}
}
|
Javascript
<script>
function binarySearch( arr, low,
high, key){
if (high < low)
return -1;
let mid = Math.floor((low + high) / 2);
if (key == arr[mid])
return mid;
if (key > arr[mid])
return binarySearch(arr, (mid + 1), high, key);
return binarySearch(arr, low, (mid - 1), key);
}
function findPivot( arr, low, high){
if (high < low)
return -1;
if (high == low)
return low;
let mid = Math.floor((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);
}
function pivotedBinarySearch( arr, n, key){
let pivot = findPivot(arr, 0, n - 1);
if (pivot == -1)
return binarySearch(arr, 0, n - 1, key);
if (arr[pivot] == key)
return pivot;
if (arr[0] <= key)
return binarySearch(arr, 0, pivot - 1, key);
return binarySearch(arr, pivot + 1, n - 1, key);
}
let arr1 = [ 5, 6, 7, 8, 9, 10, 1, 2, 3 ];
let n = arr1.length;
let key = 3;
document.write( "Index of the element is : "
+ pivotedBinarySearch(arr1, n, key));
</script>
|
PHP
<?php
function binarySearch( $arr , $low ,
$high , $key )
{
if ( $high < $low )
return -1;
$mid = floor ( $low + $high ) / 2;
if ( $key == $arr [ $mid ])
return $mid ;
if ( $key > $arr [ $mid ])
return binarySearch( $arr , ( $mid + 1),
$high , $key );
else
return binarySearch( $arr , $low ,
( $mid -1), $key );
}
function findPivot( $arr , $low , $high )
{
if ( $high < $low )
return -1;
if ( $high == $low )
return $low ;
$mid = ( $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 );
}
function pivotedBinarySearch( $arr , $n , $key )
{
$pivot = findPivot( $arr , 0, $n - 1);
if ( $pivot == -1)
return binarySearch( $arr , 0,
$n - 1, $key );
if ( $arr [ $pivot ] == $key )
return $pivot ;
if ( $arr [0] <= $key )
return binarySearch( $arr , 0,
$pivot - 1, $key );
return binarySearch( $arr , $pivot + 1,
$n - 1, $key );
}
$arr1 = array (5, 6, 7, 8, 9, 10, 1, 2, 3);
$n = count ( $arr1 );
$key = 3;
echo "Index of the element is : " ,
pivotedBinarySearch( $arr1 , $n , $key );
?>
|
Output
Index of the element is : 8
Time Complexity: O(log N) Binary Search requires log n comparisons to find the element.
Auxiliary Complexity: O(1)
Thanks to Ajay Mishra for providing the above solution.
Approach 2 (Direct Binary Search on Array without finding Pivot):
The idea is to instead of two or more passes of binary search, the result can be found in one pass of binary search.
The idea is to create a recursive function to implement the binary search where the search region is [l, r]. For each recursive call:
- We calculate the mid value as mid = (l + h) / 2
- Then try to figure out if l to mid is sorted, or (mid+1) to h is sorted
- Based on that decide the next search region and keep on doing this till the element is found or l overcomes h.
Follow the steps mentioned below to implement the idea:
- Use a recursive function to implement binary search to find the key:
- Find middle-point mid = (l + h)/2
- If the key is present at the middle point, return mid.
- Else if the value at l is less than the one at mid then arr[l . . . mid] is sorted
- If the key to be searched lies in the range from arr[l] to arr[mid], recur for arr[l . . . mid].
- Else recur for arr[mid+1 . . . h]
- Else arr[mid+1. . . h] is sorted:
- If the key to be searched lies in the range from arr[mid+1] to arr[h], recur for arr[mid+1. . . h].
- Else recur for arr[l. . . mid]
Follow the below illustration for a better understanding:
Illustration:
Input arr[] = {3, 4, 5, 1, 2}, key = 1
Initially low = 0, high = 4.
low = 0, high = 4:
=> mid = 2
=> arr[mid] = 5, which is not the desired value.
=> arr[low] < arr[mid] So, the left half is sorted.
=> key < arr[low], So the next search region is 3 to 4.
low = 3, high = 4:
=> mid = 3
=> arr[mid] = 1 = key
=> So the element is found at index 3.
The element is found at index 3.
Below is the implementation of the above idea:
C++
#include <bits/stdc++.h>
using namespace std;
int search( int arr[], int l, int h, int key)
{
if (l > h)
return -1;
int mid = (l + h) / 2;
if (arr[mid] == key)
return mid;
if (arr[l] <= arr[mid]) {
if (key >= arr[l] && key <= arr[mid])
return search(arr, l, mid - 1, key);
return search(arr, mid + 1, h, key);
}
if (key >= arr[mid] && key <= arr[h])
return search(arr, mid + 1, h, key);
return search(arr, l, mid - 1, key);
}
int main()
{
int arr[] = { 4, 5, 6, 7, 8, 9, 1, 2, 3 };
int n = sizeof (arr) / sizeof (arr[0]);
int key = 3;
int i = search(arr, 0, n - 1, key);
if (i != -1)
cout << "Index: " << i << endl;
else
cout << "Key not found" ;
}
|
C
#include <stdio.h>
int search( int arr[], int l, int h, int key)
{
if (l > h)
return -1;
int mid = (l + h) / 2;
if (arr[mid] == key)
return mid;
if (arr[l] <= arr[mid]) {
if (key >= arr[l] && key <= arr[mid])
return search(arr, l, mid - 1, key);
return search(arr, mid + 1, h, key);
}
if (key >= arr[mid] && key <= arr[h])
return search(arr, mid + 1, h, key);
return search(arr, l, mid - 1, key);
}
int main()
{
int arr[] = { 4, 5, 6, 7, 8, 9, 1, 2, 3 };
int n = sizeof (arr) / sizeof (arr[0]);
int key = 3;
int i = search(arr, 0, n - 1, key);
if (i != -1)
printf ( "Index: %d\n" , i);
else
printf ( "Key not found" );
}
|
Java
import java.io.*;
class Main {
static int search( int arr[], int l, int h, int key)
{
if (l > h)
return - 1 ;
int mid = (l + h) / 2 ;
if (arr[mid] == key)
return mid;
if (arr[l] <= arr[mid]) {
if (key >= arr[l] && key <= arr[mid])
return search(arr, l, mid - 1 , key);
return search(arr, mid + 1 , h, key);
}
if (key >= arr[mid] && key <= arr[h])
return search(arr, mid + 1 , h, key);
return search(arr, l, mid - 1 , key);
}
public static void main(String args[])
{
int arr[] = { 4 , 5 , 6 , 7 , 8 , 9 , 1 , 2 , 3 };
int n = arr.length;
int key = 3 ;
int i = search(arr, 0 , n - 1 , key);
if (i != - 1 )
System.out.println( "Index: " + i);
else
System.out.println( "Key not found" );
}
}
|
Python3
def search(arr, l, h, key):
if l > h:
return - 1
mid = (l + h) / / 2
if arr[mid] = = key:
return mid
if arr[l] < = arr[mid]:
if key > = arr[l] and key < = arr[mid]:
return search(arr, l, mid - 1 , key)
return search(arr, mid + 1 , h, key)
if key > = arr[mid] and key < = arr[h]:
return search(arr, mid + 1 , h, key)
return search(arr, l, mid - 1 , key)
if __name__ = = '__main__' :
arr = [ 4 , 5 , 6 , 7 , 8 , 9 , 1 , 2 , 3 ]
key = 3
i = search(arr, 0 , len (arr) - 1 , key)
if i ! = - 1 :
print ( "Index: % d" % i)
else :
print ( "Key not found" )
|
C#
using System;
class GFG {
static int search( int [] arr, int l, int h, int key)
{
if (l > h)
return -1;
int mid = (l + h) / 2;
if (arr[mid] == key)
return mid;
if (arr[l] <= arr[mid]) {
if (key >= arr[l] && key <= arr[mid])
return search(arr, l, mid - 1, key);
return search(arr, mid + 1, h, key);
}
if (key >= arr[mid] && key <= arr[h])
return search(arr, mid + 1, h, key);
return search(arr, l, mid - 1, key);
}
public static void Main()
{
int [] arr = { 4, 5, 6, 7, 8, 9, 1, 2, 3 };
int n = arr.Length;
int key = 3;
int i = search(arr, 0, n - 1, key);
if (i != -1)
Console.WriteLine( "Index: " + i);
else
Console.WriteLine( "Key not found" );
}
}
|
Javascript
<script>
function search(arr, l, h, key){
if (l > h)
return -1;
let mid = Math.floor((l + h) / 2);
if (arr[mid] == key)
return mid;
if (arr[l] <= arr[mid]) {
if (key >= arr[l] && key <= arr[mid])
return search(arr, l, mid - 1, key);
return search(arr, mid + 1, h, key);
}
if (key >= arr[mid] && key <= arr[h])
return search(arr, mid + 1, h, key);
return search(arr, l, mid - 1, key);
}
let arr = [ 4, 5, 6, 7, 8, 9, 1, 2, 3 ];
let n = arr.length;
let key = 3;
let i = search(arr, 0, n - 1, key);
if (i != -1)
document.write( "Index: " +i + "\n" );
else
document.write( "Key not found" );
</script>
|
PHP
<?php
function search( $arr , $l , $h , $key )
{
if ( $l > $h ) return -1;
$mid = floor (( $l + $h ) / 2);
if ( $arr [ $mid ] == $key )
return $mid ;
if ( $arr [ $l ] <= $arr [ $mid ])
{
if ( $key >= $arr [ $l ] and
$key <= $arr [ $mid ])
return search( $arr , $l ,
$mid - 1, $key );
return search( $arr , $mid + 1,
$h , $key );
}
if ( $key >= $arr [ $mid ] and
$key <= $arr [ $h ])
return search( $arr , $mid + 1,
$h , $key );
return search( $arr , $l ,
$mid -1, $key );
}
$arr = array ( 5, 6, 7, 8, 9, 10, 1, 2, 3 );
$n = sizeof( $arr );
$key = 3;
$i = search( $arr , 0, $n -1, $key );
if ( $i != -1)
echo "Index: " , $i , " \n" ;
else
echo "Key not found" ;
?>
|
Time Complexity: O(log N). Binary Search requires log n comparisons to find the element. So time complexity is O(log n).
Auxiliary Space: O(1). As no extra space is required.
Thanks to Gaurav Ahirwar for suggesting the above solution.
How to handle duplicates?
At first look, it doesn’t look possible to search in O(Log N) time in all cases when duplicates are allowed.
For example consider searching 0 in {2, 2, 2, 2, 2, 2, 2, 2, 0, 2} and {2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}.
Look into the following article to find a solution to this issue: https://www.geeksforgeeks.org/search-an-element-in-a-sorted-and-rotated-array-with-duplicates/
Similar Articles:
Please write comments if you find any bug in the above codes/algorithms, or find other ways to solve the same problem.
This approach uses linear search to find the index of the key in a sorted and rotated array. The idea is to iterate through the array and compare each element with the key until we find a match.
Algorithm
- Initialize a loop index i to 0, and iterate over the array using a for loop.
- For each element of the array, check if it is equal to the given key.
- If the key is found, return the index of the element.
- If the end of the array is reached without finding the key, return -1 to indicate that the key was not found.
C++
#include <iostream>
#include <vector>
int searchRotatedArray( const std::vector< int >& arr, int key) {
int n = arr.size();
for ( int i = 0; i < n; i++) {
if (arr[i] == key) {
return i;
}
}
return -1;
}
int main() {
std::vector< int > arr = {5, 6, 7, 8, 9, 10, 1, 2, 3};
int key = 3;
int index = searchRotatedArray(arr, key);
if (index != -1) {
std::cout << "Found at index " << index << std::endl;
} else {
std::cout << "Not found" << std::endl;
}
return 0;
}
|
Java
import java.io.*;
public class GFG {
public static int searchRotatedArray( int [] arr, int key) {
int n = arr.length;
for ( int i = 0 ; i < n; i++) {
if (arr[i] == key) {
return i;
}
}
return - 1 ;
}
public static void main(String[] args) {
int [] arr = { 5 , 6 , 7 , 8 , 9 , 10 , 1 , 2 , 3 };
int key = 3 ;
int index = searchRotatedArray(arr, key);
if (index != - 1 ) {
System.out.println( "Found at index " + index);
} else {
System.out.println( "Not found" );
}
}
}
|
Python3
def search_rotated_array(arr, key):
n = len (arr)
for i in range (n):
if arr[i] = = key:
return i
return - 1
arr = [ 5 , 6 , 7 , 8 , 9 , 10 , 1 , 2 , 3 ]
key = 3
index = search_rotated_array(arr, key)
if index ! = - 1 :
print (f "Found at index {index}" )
else :
print ( "Not found" )
|
C#
using System;
using System.Collections.Generic;
class Program
{
static int SearchRotatedArray(List< int > arr, int key)
{
int n = arr.Count;
for ( int i = 0; i < n; i++)
{
if (arr[i] == key)
{
return i;
}
}
return -1;
}
static void Main()
{
List< int > arr = new List< int > { 5, 6, 7, 8, 9, 10, 1, 2, 3 };
int key = 3;
int index = SearchRotatedArray(arr, key);
if (index != -1)
{
Console.WriteLine( "Found at index " + index);
}
else
{
Console.WriteLine( "Not found" );
}
}
}
|
Javascript
<script>
function searchRotatedArray(arr, key) {
let n = arr.length;
for (let i = 0; i < n; i++) {
if (arr[i] === key) {
return i;
}
}
return -1;
}
let arr = [5, 6, 7, 8, 9, 10, 1, 2, 3];
let key = 3;
let index = searchRotatedArray(arr, key);
if (index !== -1) {
console.log( "Found at index " + index);
} else {
console.log( "Not found" );
}
</script>
|
Time complexity of this algorithm is O(n), where n is the length of the input array.
Space complexity is O(1), as the program only uses a constant amount of extra space to store the loop index and the return value.
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!