二分查找(三)——旋转后的二分查找

LeetCode_33_SearchinRotatedSortedArray

题目分析:

二分时候关键就是利用有序性来区分往左还是往右,数组"旋转"了一下,如何二分呢。
只需要借助"单调性"即可辅助判断往左还是往右。

解法一:递归

//左开右开
public static int binarySearch(int begin, int end, int[] list, int target){
    if(begin == end)
        return target == list[begin] ? begin : -1;
    if(begin > end)
        return -1;

    int mid = begin + (end - begin) / 2;

    if(target == list[mid])
        return mid;

    if (target < list[mid]) {//比中间值小 本应往左
        //左边单调上升 且 最小值比value还大 才往右
        if(target < list[begin] && list[begin] <= list[mid])
            return binarySearch(mid + 1, end, list, target);
        else
            return binarySearch(begin, mid - 1, list, target);
    } else {//大于中间值 本应往右
        //右边打掉上升 且 最大值比value还小 才往左
        if(target > list[end] && list[mid] <= list[end])
            return binarySearch(begin, mid - 1, list, target);
        else
            return binarySearch(mid + 1, end, list, target);
    }
}

解法二:循环

//左开右开
public static int binarySearch(int begin, int end, int[] list, int target) {
    while (begin <= end) {//end一开始等于length - 1
        int mid = begin + (end - begin) / 2;
        if (list[mid] == target) return mid;
        if (list[begin] <= list[mid]) {
            if (list[begin] <= target && list[mid] >= target)
                end = mid - 1;
            else begin = mid + 1;
        }
        else {
            if (list[mid] <= target && list[end] >= target)
                begin = mid + 1;
            else end = mid - 1;
        }
    }
    return -1;
}

顺带补充如何巧妙地"旋转"数组
LeetCode_189_RotateArray

题目分析:

一言以蔽之,三次翻转。

解法:

public static void rotate(int[] list, int step) {
    step %= list.length;
    rollOver(list, 0, list.length - 1);
    rollOver(list, 0, step - 1);
    rollOver(list, step , list.length - 1);
}
//翻转数组[left,right]部分
public static void rollOver(int[] list, int start, int end){
    while(start < end){
        int temp = list[start];
        list[start++] = list[end];
        list[end--] = temp;
    }
}

你可能感兴趣的:(二分查找(三)——旋转后的二分查找)