Find the Minimum Element in A sorted and Rotated Array

Find the minimum element in a sorted and rotated array

A sorted array is rotated at some unknown point, find the minimum element in it. 

Following solution assumes that all elements are distinct.

Examples

Input: {5, 6, 1, 2, 3, 4}
Output: 1

Input: {1, 2, 3, 4}
Output: 1

Input: {2, 1}
Output: 1

A simple solution is to traverse the complete array and find minimum. This solution requires Θ(n) time.
We can do it in O(Logn) using Binary Search. If we take a closer look at above examples, we can easily figure out following pattern: The minimum element is the only element whose previous element is greater than it. If there is no such element, then there is no rotation and first element is the minimum element. Therefore, we do binary search for an element which is smaller than the previous element. We strongly recommend you to try it yourself before seeing the following are C and Java implementations. 

  • C/C++
  • Java
// C program to find minimum element in a sorted and rotated array
#include <stdio.h>
 
int findMin( int arr[], int low, int high)
{
     // This condition is needed to handle the case when array is not
     // rotated at all
     if (high < low)  return arr[0];
 
     // If there is only one element left
     if (high == low) return arr[low];
 
     // Find mid
     int mid = low + (high - low)/2; /*(low + high)/2;*/
 
     // Check if element (mid+1) is minimum element. Consider
     // the cases like {3, 4, 5, 1, 2}
     if (mid < high && arr[mid+1] < arr[mid])
        return arr[mid+1];
 
     // Check if mid itself is minimum element
     if (mid > low && arr[mid] < arr[mid - 1])
        return arr[mid];
 
     // Decide whether we need to go to left half or right half
     if (arr[high] > arr[mid])
        return findMin(arr, low, mid-1);
     return findMin(arr, mid+1, high);
}
 
// Driver program to test above functions
int main()
{
     int arr1[] =  {5, 6, 1, 2, 3, 4};
     int n1 = sizeof (arr1)/ sizeof (arr1[0]);
     printf ( "The minimum element is %d\n" , findMin(arr1, 0, n1-1));
 
     int arr2[] =  {1, 2, 3, 4};
     int n2 = sizeof (arr2)/ sizeof (arr2[0]);
     printf ( "The minimum element is %d\n" , findMin(arr2, 0, n2-1));
 
     int arr3[] =  {1};
     int n3 = sizeof (arr3)/ sizeof (arr3[0]);
     printf ( "The minimum element is %d\n" , findMin(arr3, 0, n3-1));
 
     int arr4[] =  {1, 2};
     int n4 = sizeof (arr4)/ sizeof (arr4[0]);
     printf ( "The minimum element is %d\n" , findMin(arr4, 0, n4-1));
 
     int arr5[] =  {2, 1};
     int n5 = sizeof (arr5)/ sizeof (arr5[0]);
     printf ( "The minimum element is %d\n" , findMin(arr5, 0, n5-1));
 
     int arr6[] =  {5, 6, 7, 1, 2, 3, 4};
     int n6 = sizeof (arr6)/ sizeof (arr6[0]);
     printf ( "The minimum element is %d\n" , findMin(arr6, 0, n6-1));
 
     int arr7[] =  {1, 2, 3, 4, 5, 6, 7};
     int n7 = sizeof (arr7)/ sizeof (arr7[0]);
     printf ( "The minimum element is %d\n" , findMin(arr7, 0, n7-1));
 
     int arr8[] =  {2, 3, 4, 5, 6, 7, 8, 1};
     int n8 = sizeof (arr8)/ sizeof (arr8[0]);
     printf ( "The minimum element is %d\n" , findMin(arr8, 0, n8-1));
 
     int arr9[] =  {3, 4, 5, 1, 2};
     int n9 = sizeof (arr9)/ sizeof (arr9[0]);
     printf ( "The minimum element is %d\n" , findMin(arr9, 0, n9-1));
 
     return 0;
}

Output:
The minimum element is 1
The minimum element is 1
The minimum element is 1
The minimum element is 1
The minimum element is 1
The minimum element is 1
The minimum element is 1
The minimum element is 1
The minimum element is 1

How to handle duplicates?
It turned out that duplicates can’t be handled in O(Logn) time in all cases. Thanks to Amit Jain for inputs. The special cases that cause problems are like {2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 1, 2} and {2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2}. It doesn’t look possible to go to left half or right half by doing constant number of comparisons at the middle. Following is an implementation that handles duplicates. It may become O(n) in worst case though.

  • C
  • Java
// C program to find minimum element in a sorted and rotated array
#include <stdio.h>
 
int min( int x, int y) { return (x < y)? x :y; }
 
// The function that handles duplicates.  It can be O(n) in worst case.
int findMin( int arr[], int low, int high)
{
     // This condition is needed to handle the case when array is not
     // rotated at all
     if (high < low)  return arr[0];
 
     // If there is only one element left
     if (high == low) return arr[low];
 
     // Find mid
     int mid = low + (high - low)/2; /*(low + high)/2;*/
 
     // Check if element (mid+1) is minimum element. Consider
     // the cases like {1, 1, 0, 1}
     if (mid < high && arr[mid+1] < arr[mid])
        return arr[mid+1];
 
     // This case causes O(n) time
     if (arr[low] == arr[mid] && arr[high] == arr[mid])
         return min(findMin(arr, low, mid-1), findMin(arr, mid+1, high));
 
     // Check if mid itself is minimum element
     if (mid > low && arr[mid] < arr[mid - 1])
        return arr[mid];
 
     // Decide whether we need to go to left half or right half
     if (arr[high] > arr[mid])
        return findMin(arr, low, mid-1);
     return findMin(arr, mid+1, high);
}
 
// Driver program to test above functions
int main()
{
     int arr1[] =  {5, 6, 1, 2, 3, 4};
     int n1 = sizeof (arr1)/ sizeof (arr1[0]);
     printf ( "The minimum element is %d\n" , findMin(arr1, 0, n1-1));
 
     int arr2[] =  {1, 1, 0, 1};
     int n2 = sizeof (arr2)/ sizeof (arr2[0]);
     printf ( "The minimum element is %d\n" , findMin(arr2, 0, n2-1));
 
     int arr3[] =  {1, 1, 2, 2, 3};
     int n3 = sizeof (arr3)/ sizeof (arr3[0]);
     printf ( "The minimum element is %d\n" , findMin(arr3, 0, n3-1));
 
     int arr4[] =  {3, 3, 3, 4, 4, 4, 4, 5, 3, 3};
     int n4 = sizeof (arr4)/ sizeof (arr4[0]);
     printf ( "The minimum element is %d\n" , findMin(arr4, 0, n4-1));
 
     int arr5[] =  {2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 1, 2};
     int n5 = sizeof (arr5)/ sizeof (arr5[0]);
     printf ( "The minimum element is %d\n" , findMin(arr5, 0, n5-1));
 
     int arr6[] =  {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1};
     int n6 = sizeof (arr6)/ sizeof (arr6[0]);
     printf ( "The minimum element is %d\n" , findMin(arr6, 0, n6-1));
 
     int arr7[] =  {2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2};
     int n7 = sizeof (arr7)/ sizeof (arr7[0]);
     printf ( "The minimum element is %d\n" , findMin(arr7, 0, n7-1));
 
     return 0;
}

Output:
The minimum element is 1
The minimum element is 0
The minimum element is 1
The minimum element is 3
The minimum element is 0
The minimum element is 1
The minimum element is 0

This article is contributed by Abhay Rathi. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值