33. 搜索旋转排序数组

90 阅读1分钟

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;
    
};

总结:

这是算法系列文章「二分专题」的相关题解