Find the Minimum Element in A sorted and Rotated Array

来源:互联网 发布:问卷调查软件有哪些 编辑:程序博客网 时间:2024/05/21 06:36

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: 1Input: {1, 2, 3, 4}Output: 1Input: {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>
 
intfindMin(intarr[], intlow, inthigh)
{
    // This condition is needed to handle the case when array is not
    // rotated at all
    if(high < low)  returnarr[0];
 
    // If there is only one element left
    if(high == low) returnarr[low];
 
    // Find mid
    intmid = 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])
       returnarr[mid+1];
 
    // Check if mid itself is minimum element
    if(mid > low && arr[mid] < arr[mid - 1])
       returnarr[mid];
 
    // Decide whether we need to go to left half or right half
    if(arr[high] > arr[mid])
       returnfindMin(arr, low, mid-1);
    returnfindMin(arr, mid+1, high);
}
 
// Driver program to test above functions
intmain()
{
    intarr1[] =  {5, 6, 1, 2, 3, 4};
    intn1 = sizeof(arr1)/sizeof(arr1[0]);
    printf("The minimum element is %d\n", findMin(arr1, 0, n1-1));
 
    intarr2[] =  {1, 2, 3, 4};
    intn2 = sizeof(arr2)/sizeof(arr2[0]);
    printf("The minimum element is %d\n", findMin(arr2, 0, n2-1));
 
    intarr3[] =  {1};
    intn3 = sizeof(arr3)/sizeof(arr3[0]);
    printf("The minimum element is %d\n", findMin(arr3, 0, n3-1));
 
    intarr4[] =  {1, 2};
    intn4 = sizeof(arr4)/sizeof(arr4[0]);
    printf("The minimum element is %d\n", findMin(arr4, 0, n4-1));
 
    intarr5[] =  {2, 1};
    intn5 = sizeof(arr5)/sizeof(arr5[0]);
    printf("The minimum element is %d\n", findMin(arr5, 0, n5-1));
 
    intarr6[] =  {5, 6, 7, 1, 2, 3, 4};
    intn6 = sizeof(arr6)/sizeof(arr6[0]);
    printf("The minimum element is %d\n", findMin(arr6, 0, n6-1));
 
    intarr7[] =  {1, 2, 3, 4, 5, 6, 7};
    intn7 = sizeof(arr7)/sizeof(arr7[0]);
    printf("The minimum element is %d\n", findMin(arr7, 0, n7-1));
 
    intarr8[] =  {2, 3, 4, 5, 6, 7, 8, 1};
    intn8 = sizeof(arr8)/sizeof(arr8[0]);
    printf("The minimum element is %d\n", findMin(arr8, 0, n8-1));
 
    intarr9[] =  {3, 4, 5, 1, 2};
    intn9 = sizeof(arr9)/sizeof(arr9[0]);
    printf("The minimum element is %d\n", findMin(arr9, 0, n9-1));
 
    return0;
}

Output:
The minimum element is 1The minimum element is 1The minimum element is 1The minimum element is 1The minimum element is 1The minimum element is 1The minimum element is 1The minimum element is 1The 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>
 
intmin(intx, inty) { return(x < y)? x :y; }
 
// The function that handles duplicates.  It can be O(n) in worst case.
intfindMin(intarr[], intlow, inthigh)
{
    // This condition is needed to handle the case when array is not
    // rotated at all
    if(high < low)  returnarr[0];
 
    // If there is only one element left
    if(high == low) returnarr[low];
 
    // Find mid
    intmid = 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])
       returnarr[mid+1];
 
    // This case causes O(n) time
    if(arr[low] == arr[mid] && arr[high] == arr[mid])
        returnmin(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])
       returnarr[mid];
 
    // Decide whether we need to go to left half or right half
    if(arr[high] > arr[mid])
       returnfindMin(arr, low, mid-1);
    returnfindMin(arr, mid+1, high);
}
 
// Driver program to test above functions
intmain()
{
    intarr1[] =  {5, 6, 1, 2, 3, 4};
    intn1 = sizeof(arr1)/sizeof(arr1[0]);
    printf("The minimum element is %d\n", findMin(arr1, 0, n1-1));
 
    intarr2[] =  {1, 1, 0, 1};
    intn2 = sizeof(arr2)/sizeof(arr2[0]);
    printf("The minimum element is %d\n", findMin(arr2, 0, n2-1));
 
    intarr3[] =  {1, 1, 2, 2, 3};
    intn3 = sizeof(arr3)/sizeof(arr3[0]);
    printf("The minimum element is %d\n", findMin(arr3, 0, n3-1));
 
    intarr4[] =  {3, 3, 3, 4, 4, 4, 4, 5, 3, 3};
    intn4 = sizeof(arr4)/sizeof(arr4[0]);
    printf("The minimum element is %d\n", findMin(arr4, 0, n4-1));
 
    intarr5[] =  {2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 1, 2};
    intn5 = sizeof(arr5)/sizeof(arr5[0]);
    printf("The minimum element is %d\n", findMin(arr5, 0, n5-1));
 
    intarr6[] =  {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1};
    intn6 = sizeof(arr6)/sizeof(arr6[0]);
    printf("The minimum element is %d\n", findMin(arr6, 0, n6-1));
 
    intarr7[] =  {2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2};
    intn7 = sizeof(arr7)/sizeof(arr7[0]);
    printf("The minimum element is %d\n", findMin(arr7, 0, n7-1));
 
    return0;
}

Output:
The minimum element is 1The minimum element is 0The minimum element is 1The minimum element is 3The minimum element is 0The minimum element is 1The 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
原创粉丝点击