33. 搜索旋转排序数组
1.利用数组规律二分查找
-
普通的二分查找要求必须是一个有序数组,但是会发现这里的数组进行了一个旋转,是两个有序数组的拼接,前面的数组的数值都大于后面这部分数组。
-
此种解法是利用了数组的这样一个规律:每次将数组一分为二,一定至少有一个是有序的部分。我们每次都在这个有序的部分里二分查找。
-
是否是有序数组的判断标志:nums[0]与nums[mid]比较,如果nums[mid]>=nums[0],则[0,mid]的部分是有序数组,否则[mid,n-1]的部分是有序数组。
-
在这个有序部分里的二分查找需要加一层判断:因为这个有序数组是原数组的一部分,目标值可能根本不在这个有序数组的区间里,我们要判断目标值的所在:
1.如果在该有序数组中,进行正常二分的坐标处理;
即在[0,mid]内时,target>=nums[0]才能进行二分;
在[mid,n]内时,target<=nums[n-1]才能进行二分;
2.如果不在,直接将查找区间移动到另一个数组里,在另一个数组里重新进行数组一分为二的操作。
class Solution { public: int search(vector<int>& nums, int target) { int n=nums.size(); if(n==0){ return -1; } int st=0,ed,mid; while(st<=ed){ mid=st+(ed-st)/2; if(nums[mid]==target){ return mid; } if(nums[0]<=nums[mid]){ if(target>=nums[0]&&nums[mid]>target){ ed=mid-1; }else{ st=mid+1; } }else{ if(target<=nums[n-1]&&nums[mid]<target){ st=mid+1; }else{ ed=mid-1; } } } return -1; } };