精选力扣500题 第15题 LeetCode 33,啃完吃透保你涨薪5K

本文介绍了如何使用二分查找算法解决数组在未知位置旋转后的查找问题。首先通过二分找到旋转点,然后根据旋转点确定目标值所在区域,再次二分找到目标值。提供的代码实现详细解释了整个过程,并附带了面试准备资料链接。
摘要由CSDN通过智能技术生成
  • 题目数据保证 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)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值