33. Search rotating sorted array

Insert picture description here
I only thought of O(n),
the dichotomy that I thought of,

  1. target<nums[left] then search in order on the right
  2. target>=nums[left], orderly search on the left
  3. Naturally it was wrong, so it was put on hold.

After reading the solution, it suddenly dawned on me.
Divide into two arrays by mid.
At least one of them is ordered and the range is known

  • If the target is within this range, two points are enough
  • Not in this range, search another array
class Solution {
    
    
    public int search(int[] nums, int target) {
    
    
        return searchHelp(nums,target,0,nums.length-1);
    }
    private int searchHelp(int[] nums,int target,int left,int right){
    
    
        if(left>right) return -1;
        int mid=left+((right-left)>>1);
        if(nums[mid]==target) return mid;
        if(mid-1>=left&&nums[left]<=nums[mid-1]){
    
    
            //有序在左边,且目标值在里面
            if(target>=nums[left]&&target<=nums[mid-1]){
    
    
                right=mid-1;
                while (left<=right){
    
    
                    mid=left+(right-left)/2;
                    if(nums[mid]==target) return mid;
                    if(nums[mid]>target) right=mid-1;
                    else left=mid+1;
                }
            }//不在里面,搜索右边无序的。
            return searchHelp(nums,target,mid+1,right);

        }else {
    
    
            //有序在右边,且目标在里面
            if(mid+1<nums.length&&target<=nums[right]&&target>=nums[mid+1]){
    
    
                left=mid+1;
                while (left<=right){
    
    
                    mid=left+(right-left)/2;
                    if(nums[mid]==target) return mid;
                    if(nums[mid]>target) right=mid-1;
                    else left=mid+1;
                }
            }
            return searchHelp(nums,target,left,mid-1);

        }
    }
}

There is a more concise way of writing

class Solution {
    
    
    public int search(int[] nums, int target) {
    
    
        int left=0;
        int right=nums.length-1;
        while (left<=right){
    
    
            int mid=left+((right-left)>>1);
            if(nums[mid]==target) return mid;
            if(mid-1>=left&&nums[left]<=nums[mid-1]){
    
    
                if(target<=nums[mid-1]&&target>=nums[left]){
    
    
                    right=mid-1;
                }else  left=mid+1;
            }else{
    
    
                if(mid+1<nums.length&&target>=nums[mid+1]&&target<=nums[right]){
    
    
                    left=mid+1;
                } else right=mid-1;
            }
        }
        return -1;
    }
}

About judgment

 if(mid-1>=left&&nums[left]<=nums[mid-1]){
    
    
 nums[left]<=nums[mid-1] 取等号,是为了考虑只有一个数的时候

Guess you like

Origin blog.csdn.net/qq_43179428/article/details/107126398