LeetCode 33. 搜索旋转排序数组

题目描述

给你一个升序排列的整数数组 nums ,和一个整数 target
假设按照升序排序的数组在预先未知的某个点上进行了旋转。(例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。
请你在数组中搜索 target ,如果数组中存在这个目标值,则返回它的索引,否则返回 -1 。
 
示例1:

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

示例2:

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

示例3:

输入:nums = [1], target = 0
输出:-1

提示:

  • 1 <= nums.length <= 5000
  • -10^4 <= nums[i] <= 10^4
  • nums 中的每个值都 独一无二
  • nums 肯定会在某个点上旋转
  • -10^4 <= target <= 10^4

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/search-in-rotated-sorted-array

思路解析

  1. 将该数组从中间分开,可以简单地找出哪一半是有序的;
  2. 判断 target 是否可能出现在数组的有序段,若有可能,则直接使用二分法在数组的有序段查找 target
  3. target 出现在数组的无序段,则继续将该无序段从中间一分为二,直至 target出现在有序段时为止;
  4. 加强对边界条件的判断,可以提高运行速度。

代码实现

class Solution {
private:
    int searchOrd(vector<int>& nums, int left, int right, int target) {
        int i = left;
        int j = right;
        while(i < j) {
            if(nums[i] == target)
                return i;
            if(nums[j] == target)
                return j;
            int mid = (i + j) / 2;
            if(nums[mid] > target)
                j = mid - 1;
            else if(nums[mid] == target)
                return mid;
            else 
                i = mid + 1;
        }
        return -1;
    }
    int searchSub(vector<int>& nums, int left, int right, int target) {
        int mid = (left + right) / 2;
        if(nums[left] == target)
            return left;
        if(nums[right] == target)
            return right;
        if(left >= right)
            return -1;
        if(nums[mid] == target)
            return mid;
        if(nums[mid] > nums[left]) {    // Left side is ordered
            if(nums[mid] > target && nums[left] < target)
                return searchOrd(nums, left, mid, target);
            else if(nums[mid] == target) 
                return mid;
            else
                return searchSub(nums, mid + 1, right, target);
        }
        else {                          // Right side is ordered
            if(nums[mid + 1] < target && nums[right] > target) 
                return searchOrd(nums, mid + 1, right, target);
            else if(nums[mid + 1] == target)
                return mid + 1;
            else 
                return searchSub(nums, left, mid, target);
        }
        return -1;
    }
public:
    int search(vector<int>& nums, int target) {
        return searchSub(nums, 0, nums.size() - 1, target);
    }
};
posted @ 2020-10-28 23:33  行者橙子  阅读(125)  评论(0编辑  收藏  举报