思路
题意是一个升序数组按照数组内随机的点进行旋转,判断target是否存在该数组中并返回对应的位置。
这道题使用最暴力的方法也能过但并非出题的目的。仔细想想如果查找有序数组元素存在一般使用二分查找时间复杂度O(logN)。这道题仅仅是在中间某个点的位置做了旋转,还是保留了原来有序数组很多特征,思路1:能否先找到断点和target比较,然后根据断点前后皆为有序的特征进行查找,思路2:边查找target过程中比较头尾(l,r),分三种情况:(1. r>=mid>=l则此段数组有序,二分查找之 (2.r<=mid>=l 说明左段有序 (3 r>=mid<=l说明左段有序
代码
class Solution {
public int search(int[] nums, int target) {
// 4,5,6,7,0,1,2 . 4,5,6,7,0,1,2
int size = nums.length;
if(size==0) return -1;
for(int l=0,r=size-1;;){
int mid = (l+r)>>1,numm = nums[mid];
//如果中间元素刚好是target
if(numm==target) return mid;
int numl = nums[l],numr=nums[r];
// case 1: 刚好有序
if(numl<=numm&&numm<=numr){
for(int L=l,R=r;L<=R;){
mid = (L+R)>>1;
if(nums[mid]==target) return mid;
else
if(nums[mid]<target) L = mid+1;
else R = mid-1;
}
return -1;
}
//case 2: 左段有序
if(numl<=numm&&numm>=numr){
if(target>=numl&&target<=numm) r=mid-1;
else l=mid+1;
}
// case 3: 右段有序
if(numl>=numm&&numm<=numr){
if(target>=numm&&target<=numr) l=mid+1;
else r=mid-1;
}
}
}
}