假设按照升序排序的数组在预先未知的某个点上进行了旋转。
( 例如,数组 [0,0,1,2,2,5,6] 可能变为 [2,5,6,0,0,1,2] )。
编写一个函数来判断给定的目标值是否存在于数组中。若存在返回 true,否则返回 false。
示例 1:
输入: nums = [2,5,6,0,0,1,2], target = 0
输出: true
示例 2:
输入: nums = [2,5,6,0,0,1,2], target = 3
输出: false
默认模版:
class Solution {
public boolean search(int[] nums, int target) {
}
}
解析:
在第33题(点击跳转)的基础上改的,改了返回值和加了一个补丁代码(其实就是把nums[low]==nums[high]这种情况转成nums[low]!=nums[high]就行),其他都一样。
答案:
class Solution {
//测试
public static void main(String[] args) {
Solution s=new Solution ();
/*Scanner sc=new Scanner(System.in);
String s = sc.nextLine();*/
int[] nums=new int[]{3,1,1};
System.out.println(s.search(nums, 3));
}
//题目中约定的入口
public boolean search(int[] nums, int target) {
return classifiedSearch(nums,0,nums.length-1,target);
}
//分类搜索,在这里划分各种情况,处理的是循环有序数组
public boolean classifiedSearch(int[] nums,int low,int high,int target){
if(low>high) {
return false;//处理[],也就是数组为空的情况,测试案例里有这种情况
}else{//low==high||low<high
//TODO:>>>>>>>>>>>>>>>>>>第二题的补丁
if(nums[low]==nums[high]) {
while(low<high&&nums[low]==nums[high]) {
low++;
}
}
int mid=(low+high)/2;
//接下来就是判断nums[low]、nums[high]、nums[mid]和target的大小关系了
if(nums[mid]==target)return true;
if(nums[low]<=nums[mid]) {//说明[low,mid]单调递增
if(nums[low]<=target&&target<nums[mid]) {//target在单调递增区间就二分法搜索
return binarySearch(nums, low, mid-1, target);
}else {//不在单调递增区间(即[low,mid])就肯定在子循环有序数组,子循环有序数组递归处理,又回到这个方法处理
return classifiedSearch(nums, mid+1, high, target);
}
}else {//nums[mid]<=nums[high],说明[mid,high]单调递增
if(nums[mid]<target&&target<=nums[high]) {//target在单调递增区间就二分法搜索
return binarySearch(nums, mid+1, high, target);
}else {//不在单调递增区间(即[mid,high])就肯定在子循环有序数组,子循环有序数组递归处理,又回到这个方法处理
return classifiedSearch(nums, low, mid-1, target);
}
}
}
}
//单纯的二分法搜索,搜索范围包括起始下标和结束下标,一旦进入该方法的运行,该方法的返回值就是程序结果,未找到返回-1
public boolean binarySearch(int[] nums,int low,int high,int target){
if(low>high||target<nums[low]||target>nums[high])return false;//找到最后了没找到或者是不可能找到的情况
int mid=(low+high)/2;
if(nums[mid]==target) {
return true;
}else if(nums[mid]<target) {
return binarySearch(nums, mid+1, high, target);//右边二分法搜索
}else {//nums[mid]>target
return binarySearch(nums, low, mid-1, target);//左边二分法搜索
}
}
}