Leetcode 33. 搜索旋转排序数组

题目描述:

假设按照升序排序的数组在预先未知的某个点上进行了旋转。

( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。

搜索一个给定的目标值,如果数组中存在这个目标值,则返回它的索引,否则返回 -1 。

你可以假设数组中不存在重复的元素。

你的算法时间复杂度必须是 O(log n) 级别。

示例 1:

输入: nums = [4,5,6,7,0,1,2], target = 0
输出: 4

示例 2:

输入: nums = [4,5,6,7,0,1,2], target = 3
输出: -1

解题思路如下:

首先考虑数组的长度是否为0,如果为0,输出-1.否则使用二分查找法查找存在的目标值,并返回它的索引。

在编写的二分查找的函数中,首先要确保最低位(low)小于最高位(high)。否则就不满足二分查找的条件则输出-1。接着计算中间值,如果中间值等于目标值,则直接输出下标。如果不等于在分以下两种情况进行讨论:

1.如果最低位小于等于中间位,则判断目标值是否同时在最低位(low)和中间值(middle)之间,如果满足条件采用二分查找的基本思想进行递归,用最低位和中间值-1进行查找目标值。否则用该二分查找函数的最低位和最高位分别选为middle+1和最高位。

2.如果最低位大于中间位,则判断目标值是否同时在中间位(middle)和最高位之间,如果满足条件则继续用middle+1和high进行查找。否则用low和middle-1继续查找。

Java代码如下:

class Solution {
    public int search(int[] nums, int target) {
       int n=nums.length;
       if(n== 0){
           return -1;
       }
       return binarySearch(nums,target,0,n-1);
    }
    //运用二分查找的方法查找目标数值的下标 基本方式就是二分查找的方式
    public int binarySearch(int[] nums,int target,int low,int high){
        if(low > high){
            return -1;
        }
        int middle = low+(high-low)/2;
        //如果中间值等于目标值,输出下标
        if(nums[middle] == target){
            return middle;
        }
        //如果是最低位小于中间值的情况
        if(nums[low]<=nums[middle]){
           //考虑最低位等于目标值的情况
            if(nums[low]<= target && target < nums[middle]){
                //运用递归的方法
                return binarySearch(nums,target,low,middle-1);
            }
            return binarySearch(nums,target,middle+1,high);
        }else{
            //要考虑到目标值等于最高位的情况
            if(nums[middle]< target && target <= nums[high]){
                return binarySearch(nums,target,middle+1,high);
            }
            return binarySearch(nums,target,low,middle-1);
        }
    }
    
}

注意:为什么要在nums[low]<= target && target < nums[middle]写小于等于,是因为在这个条件中需考虑到最低位等于目标值的情况。即在最低位等于目标值的情况下,可以用二分法继续查找。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值