33. 搜索旋转排序数组Leetcode

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

( 例如,数组 [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

/*
思路:
因为题目要求找到target的时间复杂度为n(logn),所以很容易想到要使用二分法求解
旋转数组,就是把后边的子数组放到前边
如:0,1,2,4,5,6,7
旋转之后又这么几种情况
0,1,2,4,5,6,7
7,0,1,2,4,5,6
6,7,0,1,2,4,5
5,6,7,0,1,2,4
4,5,6,7,0,1,2
2,4,5,6,7,0,1
1,2,4,5,6,7,0
经过观察,我们可以发现总有一半的数组是有序的
而且发现,在旋转数组中,大数在前,小数在后
就比如2,4,5,6,7,0,1
当找到2,4,5,6有序后,剩下的7,0,1中也可以看做是一个旋转数组
如果中间的那个数比后边的那个数小,说明后半段有序
反之,前半段有序
我们在有序的数组中调用二分查找法
*/
class Solution {
    public int search(int[] nums, int target) {
        
        if(nums == null || nums.length == 0)
            return -1;
    
        int start = 0;
        int end = nums.length - 1;
        
        while(start <= end){
            if(target == nums[start])
                return start;
            
            if(target == nums[end])
                return end;
            
            int middle = (start+end)/2;
            
            if(nums[middle] == target)
                return middle;
                
            if(nums[middle] < nums[end]){ //说明后半段是有序的
                if(nums[middle] < target && target < nums[end]){ //如果target在后半段中
                    start = middle + 1;
                }
                else{
                    end = middle - 1;
                }
            }else{ //说明前半段是有序的
                if(target > nums[start] && target < nums[middle]){
                    end = middle - 1;
                }else{
                    start = middle + 1;
                }
            } 
      }
        return -1;
    }
}```

猜你喜欢

转载自blog.csdn.net/qq_32682177/article/details/82772249
今日推荐