33. 搜索旋转排序数组
假设按照升序排序的数组在预先未知的某个点上进行了旋转。
( 例如,数组 [0,1,2,4,5,6,7]
可能变为 [4,5,6,7,0,1,2]
)。
搜索一个给定的目标值,如果数组中存在这个目标值,则返回它的索引,否则返回 -1
。
你可以假设数组中不存在重复的元素。
你的算法时间复杂度必须是 O(log n) 级别。
示例 1:
1 | 输入: nums = [4,5,6,7,0,1,2], target = 0 |
示例 2:
1 | 输入: nums = [4,5,6,7,0,1,2], target = 3 |
由于题目要求时间复杂度为O(log n),这提示我们使用二分查找。
数组本身不是有序的,进行旋转后只是局部有序的,还能二分查找吗?
可以发现,我们将数组从中间分成左右两部分后,左右部分中一定有一个部分是有序的。例如示例中我们从 6
这个位置分开为[4,5,6]
和 [7,0,1,2]
,其中左边 [4,5,6]
这个部分的数组是有序的。
这启示我们可以在常规二分查找上改动,每次判断分割出来的两个部分,哪个是有序的,根据有序的部分改变二分搜索的上下界。
- 如果
[1, mid-1]
是有序数组,且target
的大小满足[nums[l], nums[mid])
,则我们将搜索范围缩小到[1, mid-1]
,否则在[mid+1, r]
中寻找。 - 如果
[mid, r]
是有序数组,且target
的大小满足[nums[mid+1], nums[r])
,则我们将搜索范围缩小到[mid+1, r]
,否则在[1, mid-1]
中寻找。
1 | class Solution { |
时间复杂度 O(logN),空间复杂度 O(1)。