旋转数组是指原来排好序的数组经过旋转后形成局部有序的数组,形如【4,5,6,7,1,2,3】就是【1,2,3,4,5,6,7】经过旋转后得到的数组。
题目:给定一个数x能否在log(n)内找到这个数是否存在于旋转数组中
分析:
这个题目的难点在于如何二分地查找一个数,显然局部有序这个条件是十分有用的。我们先定义数组的左边部分为从左往右一直递增的数组,如上述例子的左边部分为【4,5,6,7】。数组的右边部分为除了左边部分的其他,如上边的例子为【1,2,3】,很容易发现,左右两部分都各自是递增序列。我们可以先判断数组的中间的那个数(整个数组的中间的数设为mid)在哪个部分,通过mid和数组最左边的数(设为start)比较即可得到mid位于哪部分,如果mid>=start则mid必定属于第一部分,因为第二本分的数都小于start,反之mid属于第二部分。
然后我们可以通过分别对mid位于第一部分和第二部分分情况讨论。
如果mid == x就返回正确。
如果mid位于第一部分时:1)只有当x<mid并且x>=start的时候对start和mid之间的数组迭代
2)否则对mid到原数组末尾(end)之间迭代。
如果mid位于第二部分时:1)只有当x>mid并且x<=end的时候对mid和end之间的数组迭代
2)否则对start到mid之间的数组迭代。
可以看出,上述分析即是一种二分查找的变形,时间复杂度为log(n)。
程序代码如下:
int find(int a[],int n,int target){
int start = 0,end = n-1,mid;
while(start <= end){
mid = (start+end)/2;
if(a[mid] == target)
return 1;
if(a[start] <= a[mid]){
if(target < a[mid] && target >= a[start])
end = mid-1;
else
start = mid+1;
}else{
if(target > a[mid] && target <= a[end])
start = mid+1;
else
end = mid-1;
}
}
return 0;
}
转载自:https://blog.csdn.net/scarecrow398966925/article/details/24852999