33. 搜索旋转排序数组
Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
题目描述
整数数组 nums 按升序排列,数组中的值 互不相同 。
在传递给函数之前,nums 在预先未知的某个下标 k(0 <= k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]](下标 从 0 开始 计数)。例如, [0,1,2,4,5,6,7] 在下标 3 处经旋转后可能变为 [4,5,6,7,0,1,2] 。
给你 旋转后 的数组 nums 和一个整数 target ,如果 nums 中存在这个目标值 target ,则返回它的下标,否则返回 -1 。
示例 1:
输入: nums = [4,5,6,7,0,1,2], target = 0
输出: 4
具体题目链接: 题目链接
思路:
思路:二分题目的思路:
确定二分边界
编写二分的代码框架
设计一个check(性质)
判断一下区间如何更新
如果更新方式写的是l=mid,r=mid-1,那么就在算mid的时候加上1
先要找两段性,可以以nums[0]为分界点,这里的细节就是nums[0]是属于和前面一段连起来的,只能判断nums[mid]>=nums[0] 或者nums[mid]<nums[0] 不能是<=,细节,一定要判断≥或者≤的时候细心
分析:
//画图,如果target在nums[0]以上的区间上
//从第一次二分得到的有序数组 开始找目标值
代码:
var search = function(nums, target) {
if(!nums)return -1;
let left = 0;
let right = nums.length-1;
while(left<right) {
let mid= left +right+1 >>1;
//先要找两段性,可以以nums[0]为分界点,这里的细节就是nums[0]是属于和前面一段连起来的,只能判断nums[mid]<=nums[0] 或者nums[mid]<nums[0] 不能是<=,细节
if(nums[mid]>=nums[0]) {
left = mid;
} else {
right = mid-1;
}
}
if(nums[0]<=target) {
left = 0;
right = right;//截取前面旋转数组的一段
}else {
left = right+1;
right = nums.length-1;//截取后面没有旋转数组的一段
}
//第二次二分查找
while(left<right) {//从第一次二分得到的有序数组 开始走目标值
let mid= left +right >>1;
if(nums[mid]>=target) {
right = mid;
} else {
left = mid+1;
}
}
if(nums[left]==target) return right;//找到了就返回值
return -1;
};
总结:
这是算法系列文章「二分专题」的相关题解