分析:
A 对于题目中定义的旋转数组,从中间一分为二。一定是被分为一个有序数组,一个旋转数组(循环数组)。
B 若对旋转数组再次从中间分割,会重复A的操作。对有序数组二分可看做普通二分查找一致操作。
定理一:只有在顺序区间内才可以通过区间两端的数值判断target是否在其中。
定理二:判断顺序区间还是乱序区间,只需要通过两端对比看看是不是在顺序区间,否则在乱序区间
通过不断的用Mid二分,根据定理二,将整个数组划分成顺序区间和乱序区间,然后利用定理一判断target是否在顺序区间,如果在顺序区间,下次循环就直接取顺序区间,如果不在,那么下次循环就取乱序区间。
class Solution {
public int search(int[] nums, int target) {
int left = 0;
int right = nums.length-1;
while(left<=right){
int mid = (left+right)/2;
if(nums[mid]==target){
return mid;
}
// 1.判断左右边数组的属性(即哪边是有序的,哪边是循环数组)
if(nums[mid] > nums[right]){
// 左侧有序,右侧是循环数组
// 2.判断target在升序数组里,还是在循环数组里
if(nums[left]<=target&&target<nums[mid]){
// 在有序数组里,也就是在左侧
right = mid-1;
}else{
left = mid+1;
}
}else{
// 左侧循环数组,右侧有序
// 2.判断target在升序数组里,还是在循环数组里
if(target>nums[mid]&&target<=nums[right]){
// 在有序数组里,也就是在右侧
left = mid+1;
}else{
right = mid-1;
}
}
}
return -1;
}
}
参考:
https://www.bilibili.com/video/BV17M411J71z/?spm_id_from=333.337.search-card.all.click&vd_source=46d50b5d646b50dcb2a208d3946b1598
https://leetcode.cn/problems/search-in-rotated-sorted-array/solutions/220083/sou-suo-xuan-zhuan-pai-xu-shu-zu-by-leetcode-solut/