Search in Rotated Sorted Array (Java)

来源:互联网 发布:mac怎么设置鼠标滚轮 编辑:程序博客网 时间:2024/05/16 07:26

Suppose a sorted array is rotated at some pivot unknown to you beforehand.

(i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2).

You are given a target value to search. If found in the array return its index, otherwise return -1.

You may assume no duplicate exists in the array.

这道题由于存在将有序数组进行了翻转,二分查找方法就不能直接用了,必须将其变化才可以正常使用,二分搜索的重点是判断到底是应该向前找还是向后找。像这道题就存在这样的问题,在全局low和high之中,数列是非有序的,而在某个局部low和high之间,数列很可能是有序的。所以首先需要一个判断条件 是否A[low] < A[high],如果小于则是有序,如果大于则是无序。

其次,判断找target的下一次二分位置是在前半段还是后半段。比如找6,不能只比较6和A[mid]的大小,因为A[mid] = 7,而7的前半段和后半段都是小于7的数,这时候需要将target和A[high]比较以及A[mid]和A[high]比较。当 targe < A[mid]时,如果A[mid]>A[high](拐点在右边)且target<=A[high](没翻转时target在拐点前半段)且A[low] > A[high](本段无序),就往后找,其他情况往前找。同理,target > A[mid]时,A[mid]<A[high](拐点在左边)且target>A[high](没翻转时target在拐点后半段)且A[low]>A[high](本段无序),就往前找,其他情况往后找。

Source1

public class Solution {    public int search(int[] A, int target) {        return BinarySearch(0, A.length - 1, A, target);    }        public int BinarySearch(int low, int high, int[] A, int target){    while(low <= high){    int mid = low + ((high - low) >> 1);    if(A[mid] > target){    if(A[high] < A[low] && target <= A[high] && A[mid] > A[high]){    low = mid + 1;    }     else high = mid - 1;    }    else if(A[mid] < target){    if(A[high] < A[low] && target > A[high] && A[mid] < A[high]){    high = mid - 1;    }    else low = mid + 1;    }    else return mid;    }    return -1;    }}


还有一种方法是用mid和low比,如果mid > low 证明左半部分有序,如果mid < low 证明右半部分有序,如果mid == low,此时的二分局部区间要么只剩一个元素,要么剩两个元素,在if之前就先判断了target是否与A[mid]相等,所以这里的else语句只需要使low++。

Test

    public static void main(String[] args){    int[] A = {4, 5, 6, 7, 0, 1, 2};    System.out.println(new Solution().search(A, 6));      }


Source2

    public int search(int[] A, int target) {        int low = 0, high = A.length - 1;        while(low <= high){        int mid = low + ((high - low) >> 1);        if(target == A[mid]) return mid;        if(A[low] < A[mid]){  //左半部有序        if(A[low] <= target && target < A[mid]){        high = mid - 1;        }        else low = mid + 1;        }        else if(A[low] > A[mid]){ //右半有序        if(A[high] >= target && target > A[mid]){        low = mid + 1;        }        else high = mid - 1;        }        else low ++;  // A[low] == A[mid] 只有两种情况 要么该局部区间一个值 要么该局部区间两个值        }        return -1;    }


0 0