Search in Rotated Sorted Array

https://leetcode.com/problems/search-in-rotated-sorted-array/

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.

解题思路:

这时一道二分查找题,与标准的binary search不同,它的数组没有排序,在某个位置被rotate了。所以我们无法直接A[mid]的值和target的大小直接用mid去更新start或者end,但是一定有方法,我们来看看。

例如一个A[]:6 7 0 1 2 4 5,mid为1。如果我们要搜1,这种情况下target<A[mid],一定在前半段。如果要找比A[mid]大的,就不一定了,有可能在后半段,也有可能在被rotate到前面去的几个(6、7)里面。那么如何判断到底在前面还是后面?就看target和A[end]也就是5的大小,如果>5,一定是被rotate到前面去的,就在前面,否在在后半段。

这样就清楚了。可是写出来出错,为什么?

考虑另一个例子,A[]:2 4 5 6 7 0 1,这种情况被rotated到前面的元素多,mid为6。这时的判断就完全相反了,比A[mid]大的,一定在后半段,但是比A[mid]小的,要和A[start]比大小,然后看到底在前半段还是后半段。

这里我们可以看到,要先根据A[mid]和与[start]或者A[end]的大小来分别讨论,但是整体思路还是比较清晰的。题目不是太难。

public class Solution {

    public int search(int[] A, int target) {

        int start = 0;

        int end = A.length - 1;

        

        while(start <= end){

            int mid = (start + end) / 2;

            if(target == A[mid]){

                return mid;

            }

            if(A[mid] < A[start]){

                //后半段一定比mid大,所以这时target一定在前面

                if(target < A[mid]){

                    end = mid - 1;

                }

                //有可能在后半段,也有可能在rotate到前面的那部分

                if(target > A[mid]){

                    if(target <= A[end]){

                        start = mid + 1;

                    }else{

                        end = mid - 1;

                    }

                }

            }else{

                //前半段一定比mid小,所以这时target一定在后面

                if(target > A[mid]){

                    start = mid + 1;

                }

                if(target < A[mid]){

                    if(target < A[start]){

                        start = mid + 1;

                    }else{

                        end = mid - 1;

                    }

                }

            }

        }

        return -1;

    }

}

update 2015/07/12:

更新了代码,先判断target是不是在有序的那段,否则就在另一段

public class Solution {

    public int search(int[] nums, int target) {

        if(nums.length == 0) {

            return -1;

        }

        int start = 0, end = nums.length - 1;

        while(start <= end) {

            int mid = (start + end) / 2;

            if(nums[mid] == target) {

                return mid;

            }

            // 必须是小于等于,因为start可能等于mid

            if(nums[start] <= nums[mid]) {

                if(target < nums[mid] && target >= nums[start]) {

                    end = mid - 1;

                } else {

                    start = mid + 1;

                }

            } else {

                if(target > nums[mid] && target <= nums[end]) {

                    start = mid + 1;

                } else {

                    end = mid - 1;

                }

            }

        }

        return -1;

    }

}

 

你可能感兴趣的:(search)