搜索旋转排序数组

QUESTION:

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

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

EXPLANATION:

首先我们看到时间复杂度是logn,那么就说明肯定是二分法了。确定了二分法,那么难点其实就出在了怎么样确定分法。普通的二分法其实就是确定target和mid值的对比来确定在左还是右的区间,那么我们有没有办法也同样使用mid值来确定呢。答案是可以的。首先,mid值如果大于start值,那么就说明左半边是递增的,否则就说明右半边是递增的。其次再确定target值在不在递增的这一边,如果不在,就说明在另外一边。经过这样的循环就能最后确定target值在哪一边了。这样就可以替代之前用mid的方式,其实还是使用了二分法的思想。
思路:
1.确定start和end
2.确认mid是否大于等于start,说明左边是正序的
2.1.左边正序的情况下判断target在不在左边(通过target,start,还有mid的值来确定)左边就将mid赋值给end
3.mid小于start说明右边是正序
3.1.右边是正序那判断target在不在右边,同样通过target,mid,end来进行判断,在右边就将start赋值给mid
4.循环结束后就是最后的结果

SOLUTION:

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