33. 搜索旋转排序数组(二分)

一、题目描述

升序排列的整数数组 nums 在预先未知的某个点上进行了旋转(例如, [0,1,2,4,5,6,7] 经旋转后可能变为 [4,5,6,7,0,1,2] )。
请你在数组中搜索 target ,如果数组中存在这个目标值,则返回它的索引,否则返回 -1 。
示例 1:
输入:nums = [4,5,6,7,0,1,2], target = 0
输出:4
示例 2:
输入:nums = [4,5,6,7,0,1,2], target = 3
输出:-1
示例 3:
输入:nums = [1], target = 0
输出:-1
提示:
1 <= nums.length <= 5000
-10^4 <= nums[i] <= 10^4
nums 中的每个值都 独一无二
nums 肯定会在某个点上旋转
-10^4 <= target <= 10^4

二、题解
方法一:使用两次二分查找
第一次二分查找,查找旋转位置
第二次二分查找,再在对应的区间查找目标值

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

方法二:使用一次二分查找
每次判断通过mid切割出来的两部分哪部分是有序的

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

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_38748148/article/details/113828213
今日推荐