题目

思路
- 一眼暴力解法,但也肯定不是让我们写暴力的。
- 将数组一分为二,首先判断左右两边是否有序,因为是旋转过后的数组,比如[5,6,7,8,9,0,1,2,3],所以一切为二的话,一定有一边是有序的,一边是无序的,可以根据arr[left]和arr[right]和arr[middle]的大小判断。
- 如果是有序数组,直接判断target和两端的大小即可,如果target在的话,二分查找。如果不在的话,抛弃这部分,去看无序数组。
- 对于无序数组,再次一分为二,重复以上操作即可实现O(log(n))的复杂度。
- 因为要用到二分查找,就顺手写了一个二分查找
public static int BinarySearch(int[] arr, int target){
int left = 0;
int right = arr.length-1;
int middle = (left+right)/2;
while(left<right && arr[middle]!=target && arr[left]!=target && arr[right]!=target){
if(arr[middle]<target) left = middle;
else right = middle;
if((left+right)/2==middle) break;
else middle = (left+right)/2;
}
if(arr[middle]==target) return middle;
if(arr[left]==target) return left;
if(arr[right]==target) return right;
else return -1;
}
代码
public static int BinarySearch(int[] arr, int left,int right,int target){
int middle = (left+right)/2;
while(left<right && arr[middle]!=target && arr[left]!=target && arr[right]!=target){
if(arr[middle]<target) left = middle;
else right = middle;
if((left+right)/2==middle) break;
else middle = (left+right)/2;
}
if(arr[middle]==target) return middle;
if(arr[left]==target) return left;
if(arr[right]==target) return right;
else return -1;
}
public static int search(int[] nums, int target) {
if(nums.length==1) return (nums[0]==target)?0:-1;
int left = 0;
int right = nums.length-1;
int middle = nums.length/2;
while(left<right){
if(nums[middle]==target) return middle;
if(nums[left]==target) return left;
if(nums[right]==target) return right;
boolean targetlocal=false;
boolean leftyouxu = false;
if(nums[left]<nums[middle]) leftyouxu=true;
if(leftyouxu){
if(nums[left]<=target && nums[middle]>=target) targetlocal=false;
else targetlocal=true;
}else{
if(nums[middle]<=target && nums[right]>=target) targetlocal=true;
else targetlocal=false;
}
if(targetlocal){
if(leftyouxu){
left = middle;
middle = (left+right)/2;
}else{
int ans = BinarySearch(nums,middle,right,target);
return ans;
}
}else{
if(leftyouxu){
int ans = BinarySearch(nums,left,middle,target);
return ans;
}else {
right=middle;
middle = (left+right)/2;
}
}
}
if(nums[middle]==target) return middle;
if(nums[left]==target) return left;
if(nums[right]==target) return right;
return -1;
}