Corner cases: 1 duplicate elements. 2. the array is not rotated at all.
1. Search in rotated sorted array.
https://oj.leetcode.com/problems/search-in-rotated-sorted-array/
2. Search in rotated sorted array with duplicates.
https://oj.leetcode.com/problems/search-in-rotated-sorted-array-ii/
3. Find the rotation point (find the minimum element in the array)
the below code seems okay even if there are duplicates.
#include <iostream>
#include <cstdio>
using namespace std;
int findRotatePoint(int array[], int n)
{
int left=0, right = n-1;
while(left <= right)
{
int mid = left + (right-left)/2;
if(mid > 0 && array[mid] < array[mid-1])
return mid;
if(mid < right && array[mid] < array[right])
right = mid-1;
else
left = mid+1;
}
return 0;
}
// Driver program to test above functions
int main()
{
int arr1[] = {5, 6, 1, 2, 3, 4};
int n1 = sizeof(arr1)/sizeof(arr1[0]);
int res1 = findRotatePoint(arr1, n1);
cout << res1 << "\t" << arr1[res1] << endl;
int arr2[] = {1, 2, 3, 4};
int n2 = sizeof(arr2)/sizeof(arr2[0]);
int res2 = findRotatePoint(arr2, n2);
cout << res2 << "\t" << arr2[res2] << endl;
int arr3[] = {1};
int n3 = sizeof(arr3)/sizeof(arr3[0]);
int res3 = findRotatePoint(arr3, n3);
cout << res3 << "\t" << arr3[res3] << endl;
int arr4[] = {1, 2};
int n4 = sizeof(arr4)/sizeof(arr4[0]);
int res4 = findRotatePoint(arr4, n4);
cout << res4 << "\t" << arr4[res4] << endl;
int arr5[] = {2, 1};
int n5 = sizeof(arr5)/sizeof(arr5[0]);
int res5 = findRotatePoint(arr5, n5);
cout << res5 << "\t" << arr5[res5] << endl;
int arr6[] = {5, 6, 7, 1, 2, 3, 4};
int n6 = sizeof(arr6)/sizeof(arr6[0]);
int res6 = findRotatePoint(arr6, n6);
cout << res6 << "\t" << arr6[res6] << endl;
int arr7[] = {1, 2, 3, 4, 5, 6, 7};
int n7 = sizeof(arr7)/sizeof(arr7[0]);
int res7 = findRotatePoint(arr7, n7);
cout << res7 << "\t" << arr7[res7] << endl;
int arr8[] = {2, 3, 4, 5, 6, 7, 8, 1};
int n8 = sizeof(arr8)/sizeof(arr8[0]);
int res8 = findRotatePoint(arr8, n8);
cout << res8 << "\t" << arr8[res8] << endl;
int arr9[] = {3, 4, 5, 1, 2};
int n9 = sizeof(arr9)/sizeof(arr9[0]);
int res9 = findRotatePoint(arr9, n9);
cout << res9 << "\t" << arr9[res9] << endl;
int arr10[] = {10, 10, 10, 3, 10};
int n10 = sizeof(arr10)/sizeof(arr10[0]);
int res10 = findRotatePoint(arr10, n10);
cout << res10 << "\t" << arr10[res10] << endl;
return 0;
}
4. Find k-th smallest number (without duplicate)
if the rotation point is unknown, first find rotation point.
/*Given a rotated sorted array and count 'k' by which the array is rotated
clockwise, find Nth highest number. Assume that array was sorted in
ascending order before rotation*/
int findNthHigehest(int* arr, int size, int k, int n)
{
assert(arr);
assert(size > 0);
return arr[(n+k-1)%size];
}
/*Given a rotated sorted array and count 'k' by which the array is rotated
clockwise is not known, find Nth highest number. Assume that array was sorted in
ascending order before rotation. For finding minimum element pass 'n' as 1
and for finding maximum pass 'n' as size.*/
int findNthHigehest(int* arr, int size, int n)
{
assert(arr);
assert(size > 0);
int k = findRotationCount(arr, size);
return arr[(n+k-1)%size];
}
5. find the first occurence of a target (with duplicates)
http://www.careercup.com/question?id=5705265454252032
//因为找第一个出现的位置,优先判断左半部分,如果不包含,再去找右半部分。
#include <iostream>
#include <cstdio>
#include <climits>
using namespace std;
int findFirstTarget(int array[], int n, int target)
{
int left=0, right = n-1;
int firstPos = INT_MAX;
while(left <= right)
{
int mid = left + (right-left)/2;
if(array[mid] == target)
firstPos = min(firstPos, mid);
if(array[left] <= target && target <= array[mid-1])
right = mid-1;
else
left = mid+1;
}
return firstPos;
}
// Driver program to test above functions
int main()
{
int arr1[] = {10, 10, 10, 3, 10};
int n1 = sizeof(arr1)/sizeof(arr1[0]);
int res1 = findFirstTarget(arr1, n1, 10);
cout << res1 << "\t" << arr1[res1] << endl;
int arr2[] = {5, 6, 7, 1, 2, 3, 4, 4};
int n2 = sizeof(arr2)/sizeof(arr2[0]);
int res2 = findFirstTarget(arr2, n2, 4);
cout << res2 << "\t" << arr2[res2] << endl;
int arr3[] = {3, 4, 5, 6, 1, 2 };
int n3 = sizeof(arr3)/sizeof(arr3[0]);
int res3 = findFirstTarget(arr3, n3, 2);
cout << res3 << "\t" << arr3[res3] << endl;
int arr4[] = {8,8,9,1,3,5,7};
int n4 = sizeof(arr4)/sizeof(arr4[0]);
int res4 = findFirstTarget(arr4, n4, 8);
cout << res4 << "\t" << arr4[res4] << endl;
return 0;
}