leetcode 6. 在有序数组旋转后搜索 Search in Rotated Sorted Array

Search in Rotated Sorted Array
难度:Hard


Suppose a sorted array is rotated at some pivot unknown to you beforehand.

(i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2).

You are given a target value to search. If found in the array return its index, otherwise return -1.

You may assume no duplicate exists in the array.

(下一题将研究存在重复的情况Search in Rotated Sorted Array II)


解题思路:
对于数组搜索问题,时间复杂度大致有三种 O(n),O(lg n),O(1)
其中线性复杂度 O(n) ,即顺序搜索;而常数时间 O(1) 一般通过关键字索引或Hash表实现;而对数复杂度 O(lg n) ,常通过二分查找、二叉搜索树类型实现

对于本题中的条件是有序数组的变形,因此可联想到“快速排序的选择”–二分查找
难点就是寻找划分元素和对划分元素左右两侧的递归条件及其边界

对于划分元素,容易想到直接取中间 m = (l+r) / 2; 数组边界 [l, r)
对实例观察:必须强化寻找所有可能案例的能力
0 1 2 4 5 6 7
4 5 6 7 0 1 2
5 1 3
3 1
nums[m] > nums[l] : (l, m-1)单增
nums[m] <= nums[l] : (m+1, r)单增
注:
- 当数组取边界 [l, r) 时,m取到居中靠右(如在2个元素时,m = 1),因此此时,应该比较nums[m], num[l]
- 当取数组边界 [l, r] 时,m取到居中靠左(如在2个元素时,m = 0),因此此时,应该比较nums[m], num[r];

数组边界为 [l,r) – O(lg n)

class Solution {
public:
    //nums 数组边界为 [l,r)
    int searchR(vector<int>& nums,int l, int r, int target) {
        if (r <= l)
            return -1;
        int m = (l+r) / 2;
        if (nums[m] == target)
            return m;

        if (nums[l] < nums[m]) {
            if (target >= nums[l] && target < nums[m])
                return searchR(nums, l, m, target);
            else
                return searchR(nums, m+1, r, target);
        } else {
            if(target > nums[m] && target <= nums[r-1])
                return searchR(nums, m+1, r, target);
            else
                return searchR(nums, l, m, target);    
        }
    }

    int search(vector<int>& nums, int target) {
        return searchR(nums, 0, nums.size(), target);
    }
};

数组边界[l, r] –注意传入数组的边界

class Solution {
public:
                    //nums 数组边界为 [l,r]
    int searchR(vector<int>& nums,int l, int r, int target) {
        if (r < l)
            return -1;
        int m = (l+r) / 2;
        if (nums[m] == target)
            return m;

        if (nums[r] > nums[m]) {
            if (target > nums[m] && target <= nums[r])
                return searchR(nums, m+1, r, target);
            else
                return searchR(nums, l, m-1, target);
        } else {
            if(target >= nums[l] && target < nums[m])
                return searchR(nums, l, m-1, target);
            else
                return searchR(nums, m+1, r, target);    
        }


    }
    int search(vector<int>& nums, int target) {
        return searchR(nums, 0, nums.size()-1, target);
    }
};

顺序搜索 O(n) – 不推荐

class Solution {
public:

    int search(vector<int>& nums, int target) {
        int i = 0;
        for (; i < nums.size(); i++) {
            if (nums[i] == target)
                break;
        }
        if(nums.size() == i)
            return -1;
        else
            return i;
    }
};

(下一题将研究存在重复的情况Search in Rotated Sorted Array II)

你可能感兴趣的:(LeetCode)