Q: A magic index in an array A[1...n-1] is defined to be an index such that A[i] = i. Given a sorted array of distince integers, write a methon to find a magic index, if one exits, in array A。
FOLLOW UP
What if the values are not distinct?
A:直接用二分法查找即可。
FOLLOW UP:
如果数组中存在重复元素,那么就需要对二分法进行改进,因为对于A[mid] < mid的情况,还是不能判定magic index在mid的左边还是右边,下面的例子就说明了这个问题:
-10 | -5 | 2 | 2 | 2 | 3 | 4 | 7 | 9 | 12 | 13 |
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
同理rightstart = max(A[mid], mid+1)
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
template <class T>
int getArrayLen(T& array){
return (sizeof(array) / sizeof(array[0]));
}
int magicIndex(int array[], int start, int end) {
while (start <= end) {
int mid = start + (end-start)/2;
if (array[mid] == mid) {
return mid;
} else if (array[mid] > mid) {
end = mid - 1;
} else {
start = mid + 1;
}
}
return -1;
}
int magicIndexFollowUp(int A[], int start, int end, int n) {
if (end < start || start < 0 || end >= n) {
return -1;
}
int mid = start + (end-start)/2;
if (A[mid] == mid) {
return mid;
}
//search left
int leftend = min(A[mid], mid - 1);
int left = magicIndexFollowUp(A, start, leftend, n);
if (left >= 0) {
return left;
}
//search right
int rightstart = max(A[mid], mid + 1);
int right = magicIndexFollowUp(A, rightstart, end, n);
return right;
}
int magicIndexFollowUp(int array[], int n) {
return magicIndexFollowUp(array, 0, n-1, n);
}
int main() {
int array[] = {-2,-1,1,3,6,7};
cout<<magicIndex(array, 0, 5)<<endl;
int array2[] = {-10,-5,2,2,2,3,4,7,9,12,13};
int n = getArrayLen(array2);
cout<<magicIndexFollowUp(array2, n)<<endl;
return 0;
}