Description
Suppose an array sorted in ascending order 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.
Your algorithm’s runtime complexity must be in the order of O(log n).
Example 1:
1 | Input: nums = [4,5,6,7,0,1,2], target = 0 |
Example 2:
1 | Input: nums = [4,5,6,7,0,1,2], target = 3 |
解法
查找的题,又要求时间复杂度为O(logn),显然是要采用二分的算法,二分可以一次将查找范围缩小一半。而二分的前提应该是查找数组为有序的,观察一下这道题的数组情况。
对于数组[0 1 2 4 5 6 7] 共有下列七种旋转方法:
0 1 2 4 5 6 7
7 0 1 2 4 5 6
6 7 0 1 2 4 5
5 6 7 0 1 2 4
4 5 6 7 0 1 2
2 4 5 6 7 0 1
1 2 4 5 6 7 0
可以发现,无论如何旋转,至少有一半的序列都是有序的,仔细想想,也很有道理。所以,可以随意选取当前查找范围的一半,如果当前无序,则另一半必有序。以右区间为例,有序的判断条件为nums[mid] <= nums[right]。每次只处理有序区间,判断当前元素是否位于该有序区间之中,是,则将区间缩小为有序区间,否,则将区间缩小为无序区间,无序区间下一次循环再判断其左右子区间有序状态做进一步地缩小。这样,每次缩小的范围为当前区间的一半。
具体代码如下:
1 | class Solution { |