【Leetcode】33. Search in Rotated Sorted Array

来源:互联网 发布:红蜘蛛软件年费 编辑:程序博客网 时间:2024/06/07 14:30

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

一个递增的没有重复元素的数组,做一次移位操作,然后在数组中查找偶一个元素返回索引,如果没有返回-1。

首先要明白递增数组移位以后的特征,必然是前半段总比后半段大,而且各自内部是有序的。很明显这是一个特殊的二分查找。仍然是取得中间元素a[m],之后的比较过程和常规的二分不同。

以下特征是关键点:一个移位数组被a[m]切为两段,那么必然有一段是有序的,另一段是跳跃的。

我们只需要判断a[m]两侧是有序的还是跳跃的,可以判断左边,即a[low]如果小于等于a[m],说明[low,m]这段闭区间是有序的,那么[m+1, high]就是跳跃的。这里需要注意必须是有等于才行,否则如果只有两个元素,那么a[m]等于a[low],此时[low,m]这段闭区间原则上是有序的,如果不加等号,那么就会判定[m, high]是有序的,这是错误的。举个例子array = {2,1},low = 0, high = 1, m = 0。此时array[low] == array[m],那么如果不加等号判断,就会认为[low, m]是无序的,那么[m, high]是有序的,即{2,1}有序,显然错误。

接下来,是看target的值,只看左侧有序的情况,如果a[low]<=target<=a[m],那么就需要在左半边查找,否则就在右半边。我们只需要找有序的那边,只要不在有序的那段,就在跳跃段查找。如果从跳跃段下手,仍然无法确定是在左侧还是右侧。这里也需要注意必须加上等于的情况,因为我们是在一段有序闭区间里面查找。

代码:

 public int search(int[] nums, int target) {        if(nums == null)        return -1;        int low = 0, high = nums.length - 1;        while(low <= high){        int m = (low + high) / 2;        if(nums[m] == target)        return m;        if(nums[low] <= nums[m]){        if(nums[low] <= target && target <= nums[m])        high = m - 1;        else         low = m + 1;         }else{        if(nums[m] <= target && target <= nums[high])        low = m + 1;        else        high = m - 1;        }        }        return -1;    }


原创粉丝点击