LeetCode解题记录(33)——搜索旋转排序数组

LeetCode解题记录——搜索旋转排序数组

    • 题目描述
    • 示例
    • 题目理解
    • 解题思路

题目描述

假设按照升序排序的数组在预先未知的某个点上进行了旋转。

( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。

搜索一个给定的目标值,如果数组中存在这个目标值,则返回它的索引,否则返回 -1

你可以假设数组中不存在重复的元素。

你的算法时间复杂度必须是 O ( l o g n ) O(log n) O(logn) 级别。

示例

输入: nums = [4,5,6,7,0,1,2], target = 0
输出:4

输入: nums = [4,5,6,7,0,1,2], target = 3
输出:-1

题目理解

题目要求了复杂度,对于log级别的复杂度,基本可以确定使用二分查找进行搜索。

对于旋转数组其实可以将它看作是两个有序数组的组合。

解题思路

二分查找的思路,是每次减少一般的查找量。这里我们基于二分查找的思路,设置头尾标示,加上一些其他的判断。

  • 如果命中则直接返回下标
  • 如果目标值小于中间值,会有两种情况
    • 如果中间值大于头位置的值,说明前半部分为一个升序有序数组,后半部分包含两个有序数组,目标值只会在之后出现,因此将头位置移动到中间位置后一个
    • 如果中间值小于头位置的值,则表示前半部分为两个有序数组的组合,后半部分为一个有序数组,这时候需要判断目标值和尾位置值的大小,如果目标值小于等于尾位置值,说明在后半部分,则头位置移动,反之,在前半部分,尾位置移动。
  • 如果目标值大于中间值,则是与上述情况相反的两种情况,这里就不过多赘述。

对应代码如下:

int search(vector& nums, int target) {
    int b = 0,e = nums.size()-1;
    while(b<=e){
        int mid = (b+e)/2;
        if(nums[mid] == target)
            return mid;
        if(target>nums[mid]){
            if(nums[mid]>=nums[b])
                b = mid+1;
            else if(target<=nums[e])
                b = mid+1;
            else
                e = mid-1;
        }else{
            if(nums[mid]<=nums[e])
                e = mid-1;
            else if(target>=nums[b])
                e = mid-1;
            else
                b = mid+1;
        }
    }
    return -1;
}

运行结果如下:
LeetCode解题记录(33)——搜索旋转排序数组_第1张图片

我的所有解题代码都会上传到我的github上,需要可以自取。

LeetCode解题代码

你可能感兴趣的:(LeetCode解题笔记)