-
题目数据保证
nums
在预先未知的某个下标上进行了旋转 -
-10^4 <= target <= 10^4
2、思路
(二分) O ( l o g n ) O(logn) O(logn)
1、先找到旋转点,在旋转点左边的点都比nums[0]
大,右边的点都比nums[0]
小,因此可以用二分找到该点
-
当
nums[mid] >= nums[0]
时,往右边区域找,l = mid
。 -
当
nums[mid] < nums[0]
时,往左边区域找,r = mid - 1
。
2、找到旋转点l后,可以知道[0,l - 1]
,[l,n - 1]
是两个有序数组,判断出target
的值在哪个有序数组中,确定好二分的区间[l,r]
3、在[l,r]
区间中,由于该区域也具有单调性,通过二分找到该值的位置
-
当
nums[mid] >= target
时,往左边区域找,r = mid
。 -
当
nums[mid] < target
时, 往右边区域找,l = mid + 1
。
4、若最后找到的元素nums[r] != target
,则表示不存在该数,返回-1
,否则返回该数值
3、代码
class Solution {
public:
int search(vector<int>& nums, int target) {
if(nums.empty()) return -1;
//先二分转折点 二分>=nums[0]的最右边
int l = 0, r = nums.size() - 1;
while( l < r)
{
int mid = (l + r + 1)/2;
if(nums[mid] >= nums[0]) l = mid;
else r = mid - 1;
}
if(target >= nums[0]) l = 0; //target在左半边区域
else l = r + 1, r = nums.size() - 1; //target在右半边区域
while( l < r)
{
int mid = ( l + r)/2;
if( nums[mid] >= target) r = mid;
else l = mid + 1;
}
if(nums[r] == target) return r;//二分的while循环的结束条件是l>=r,所以在循环结束时l有可能会大于r,此时就可能导致越界,基本上二分问题优先取r都不会翻车。
return -1;
}
};
### 笔者福利
##### 以下是小编自己针对马上即将到来的金九银十准备的一套“面试宝典”,不管是技术还是HR的问题都有针对性的回答。
**有了这个,面试踩雷?不存在的!**
##### 需要这套“面试宝典”的,[点击这里即可免费获取](https://gitee.com/vip204888/java-p7)!回馈粉丝,诚意满满!!!
![](https://img-blog.csdnimg.cn/img_convert/708d4b175dac64861e53d09bdbbb139e.png)
![](https://img-blog.csdnimg.cn/img_convert/541342a4477c3b36b6ae8578c5d80331.png)
![](https://img-blog.csdnimg.cn/img_convert/610677ce4fc6586452b3ec3aef0b8769.png)
[外链图片转存中...(img-KOZFnvrF-1628633475500)]
[外链图片转存中...(img-yp4nvmy1-1628633475502)]
[外链图片转存中...(img-ZIViyR8K-1628633475504)]
![](https://img-blog.csdnimg.cn/img_convert/5131d43a9636af0bdaccd501d43ca880.png)