1.题目
假设按照升序排序的数组在预先未知的某个点上进行了旋转。
( 例如,数组 [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
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/search-in-rotated-sorted-array
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
2.题解
C++最简洁的二分法分类讨论
每次二分,左半部分和右半部分至少有一边是有序的,以此为条件可以分成两种情况:
1、左半边是有序的
(1) target落在左半边
(2) otherwise
2、右半边是有序的
(1) target落在右半边
(2) otherwise
综上所述,一共两种可能性,这两种情况各自又有两种可能性,代码如下:
class Solution
{
public:
int search(vector<int>& nums, int target)
{
if(nums.size()==0) return -1;
int left=0,right=nums.size()-1,mid=0;
while(left<=right)
{
mid=(left+right)/2;
if (target == nums[mid])
{
return mid;
}
else if (nums[mid] < nums[right]) //区别经典binsearch: 要判断那部分是正常的,不可能左右都是不正常的
{
//说明右边是正常的,是sorted的
//这也是有区别的地方,不能光判大于就行了,必须要落在右边的区间才行因为可能你要的那个数折回左边去了
//考虑 ,6,7,8,9,1,2,3,4,5 这个序列,如果 我选的pivot是2,轮转的基准点是1,要找的是9,那么判断大于2肯定是不行的,必须要在(2-5]这个区间里。
if (target > nums[mid] && target <= nums[right])
{
left = mid + 1;
}
else
{
right = mid - 1;
}
}
else
{
//左边是正常的,是排序的
//跟上面同理,不再解释了
if (target < nums[mid] && target >= nums[left])
{
right = mid - 1;
}
else
{
left = mid + 1;
}
}
}
return -1;
}
};