力扣33:Search In Rotated Sorted Array 搜索旋转排序数组 medium 题目描述: 1.整数数组 nums 按升序排列,数组中的值 互不相同 2.在传递给函数之前,nums 在预先未知的某个下标 k(0 <= k < nums.length)上进行了 旋转, 使数组变为 [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]](下标 从 0 开始 计数)。 例如, [0,1,2,4,5,6,7] 在下标 3 处经旋转后可能变为[4,5,6,7,0,1,2] 。 3.给你 旋转后 的数组 nums 和一个整数 target ,如果 nums 中存在这个目标值 target ,则返回它的下标,否则返回 -1 思路1: 4,5,6,7,0,1,2 中间mid值7大于4,则4,5,6,7是有序的,接下来判断target是否在这段有序数据中,在则将end=mid,开始进行二分查找 若target不在4,5,6,7,那么继续看后一段7,0,1,2,将start=mid也就是从7开始,中间值mid是0,0小于7,则0,1,2是有序的, 判断target在0,1,2中,则将start=mid即从0开始进行二分查找,若不在,则将end=mid,此时start=7, end=0,不符合循环条件, 判断num[start]和num[end]是否命中 思路2: 将数组拆分成两段,分别调用二分查找
方法一:
public static int search(int[] num,int target){
//1.边界
if (num==null||num.length==0) return -1;
//2.初始化端点
int start=0;
int end=num.length-1;
int mid;
//3.循环 {5,1,3};
while(start+1<end){
mid=start+(end-start)/2;
if (num[mid]==target) return mid;
//中间值所在上游有序
if (num[mid]>num[start]){
//目标值在上游
if (target>=num[start]&&target<=num[mid]) end=mid;
//目标值在下游
else start=mid;
}else {
//中间值在下游
if (target>=num[mid]&&target<=num[end]) start=mid;
else end=mid;
}
}
if (num[start]==target) return start;
if (num[end]==target) return end;
return -1;
}
方式二;
public static int search2(int[] nums, int target) {
if (nums==null||nums.length==0) return -1;
int i=0;
int j=0;
int index=-1;
int index1 = -1;
//只有一个元素 比如[1] 1
if (nums.length==1){
if (nums[0]==target) return 0;
else return -1;
}
//只有两个,如果是升序,放行,但比如[3,1] 1 这种情况变成降序,而下方的二分方法是升序的
if (nums[0]>nums[1]){
if (nums[0]==target) return 0;
if (nums[1]==target) return 1;
}
if (nums[0]<nums[1]){ //升序
for(;i<nums.length-1;i++){
if (nums[i]>nums[i+1]) break;
}
index = binarySearch(nums, target,0, i);
index1 = binarySearch(nums, target, i+1, nums.length - 1);
return index==-1?(index1==-1?-1:index1):index;
}
if (nums[0]>nums[1]){ //降序
for (; j < nums.length-1; j++) {
if (nums[j]<nums[j+1]) break;
}
index = binarySearch(nums, target,0, j);
index1 = binarySearch(nums, target, j+1, nums.length - 1);
return index==-1?(index1==-1?-1:index1):index;
}
return -1;
}
public static int binarySearch(int[] nums,int target,int s,int i){
//0.定义左右端点
int start=s;
int end=i;
//1.循环 直到start和end相邻结束
while(start<=end){
//2.取中间位置
//int mid=(start+end)/2; 不建议这种取中间值,当start和end值很大时,容易越界
int mid=start+(end-start)/2;
if (target==nums[mid]) return mid;
if (target>nums[mid]) start=mid+1;
if (target<nums[mid]) end=mid-1;
}
return -1;
}