Search in Rotated Sorted Array

来源:互联网 发布:淘宝评价回复感谢语 编辑:程序博客网 时间:2024/06/13 20:43

Suppose an array sorted in ascending order 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.


解题思路:

1. 问题中序列被分成了两段,每段都是有序的;

2. 如果把序列从中间一分为二,必然至少有一半是有序的,或是左半部分有序,或是右半部分有序,或是都有序;

3. 为简单起见, 对于第一个有序的部分,应用二分查找进行搜索,剩下的另外一半作为原问题(规模缩小)进行递归处理;

4. 总的时间复杂度为o(logn)

完整代码:

#include <iostream>
#include <vector>

using namespace std;

class Solution {

public:
    int search(vector<int>& nums, int target) {

        return entry(nums,0,nums.size()-1,target);
        
    }

private:
    int entry(vector<int>& nums, int left, int right,int target)
    {
        if(left > right)return -1;
        if(left == right)
        {
            if(nums[left] == target)return left;
            return -1;
        }
        if(left+1 == right)
        {
            if(nums[left] == target)return left;
            if(nums[right] == target)return right;
            return -1;
        }


        int mid = (left + right)/2;
        int pos;

        if(nums[left] < nums[mid])
        {
            pos = binarySearch(nums,left,mid,target);
            if(pos != -1)return pos;
            
            return entry(nums,mid+1,right,target);
            
        }
       else if(nums[left] > nums[mid])
        {
            pos = binarySearch(nums,mid,right,target);
            if(pos != -1)return pos;

            return entry(nums,left,mid-1,target);
        }
        else
        {
            if(nums[left] == target)return left;
            if(nums[right] == target)return right;
            return -1;
        }

    }
    int binarySearch(vector<int>& nums, int left, int right,int target)
    {
        int mid = (left + right)/2;

        while(left <= right)
        {
            if(nums[mid] > target)
                right = mid-1;
            else if(nums[mid] < target)
                left = mid+1;
            else
                return mid;

            mid = (left + right)/2;
        }
        return -1;
    }
};


void main(){

    vector<int> nums;
    
    int tmp;
    while(cin >> tmp)
        nums.push_back(tmp);

    Solution s;
    cout << s.search(nums,1) << endl;
}