33、搜索旋转排序数组
假设按照升序排序的数组在预先未知的某个点上进行了旋转。
( 例如,数组 [0,1,2,4,5,6,7]
可能变为 [4,5,6,7,0,1,2]
)。
搜索一个给定的目标值,如果数组中存在这个目标值,则返回它的索引,否则返回 -1 。
你可以假设数组中不存在重复的元素。
你的算法时间复杂度必须是 O(log n) 级别。
####示例 1:
输入: nums = [4,5,6,7,0,1,2], target = 0
输出: 4
示例 2:
输入: nums = [4,5,6,7,0,1,2], target = 3
输出: -1
解题思路
- 二分本质,找出满足进入分支的条件,也可能是复合分支判断
- 增加判断分支
- 数组的特点:每一次二分,要么
[l,mid]
是递增序列,要么[mid,r]
是递增序列 - 先求出那边是递增序列,然后再进一步判断,是否可以进入递增的数组进行查找,否则,就进入非递增部分
- 本题有两类分支:
- 外分支为:递增和非递增
- 内分支为:target在递增序列中和在非递增序列中
代码
class Solution {
public int search(int[] nums, int target) {
// 特殊二分查找
int len = nums.length;
int l = 0;
int r = len - 1;
while (l <= r) {
if (nums[l] == target) return l;
if (nums[r] == target) return r;
int mid = (l + r + 1) >> 1;
if (nums[mid] == target) {
return mid;
}
if (nums[mid] < nums[r]) {// 右侧有序
if (nums[mid] < target && target < nums[r]) {// 正常二分
l = mid + 1;
} else {// 特殊二分
r = mid - 1;
}
} else { // 左侧有序
if (nums[mid] > target && nums[l] < target) {// 正常二分
r = mid - 1;
} else {// 特殊二分
l = mid + 1;
}
}
}
return -1;
}
}
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 1056615746@qq.com