[LeetCode]Search in Rotated Sorted Array

No.33,Search in Rotated Sorted Array 

这道题最喜感的是,前一天刚做完,第二天某人的面试就遇到了。

这道题把一个排好序的数组截断,把前面的一段拼到后面的一段。例如0124567变成了4567012,在这样的数组中查找一个数的index。

既然局部有序,那么这道题肯定会有O(logn)的解法。

一种方法是先找到截断点,利用二分的方式,找到某个点比它左边的小,开销为logn,再比较数组最左端和要查找的值,在相应的一段中查找,也是logn。

第二种方法实现起来更简洁,比上一种快一倍,直接开销为O(logn)。直接二分查找,只不过if的条件比较复杂。

二分后,

如果中间点和查找值相同,那么直接返回中间点的index。

如果数组最左端值小于中间点,说明还没达到截断点,此时比较中间点和查找值,如果中间点大于查找值并且查找值大于等于最左端的值,说明要查找的就在左边的一半中,再进行二分;否则说明在右边的一半中。

如果数组最左端的值大于中间点,说明已经到达截断点了,此时如果查找值大于等于最左端的值,或者查找值小于等于中间值,说明在左边的一半中,否则在右边的一半。

如果数组最左端值等于中间点,直接left++过掉最左端值。

第一种方法实现:

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int n=nums.size();
        if(n==0){
            return -1;
        }
        int pos=findPos(0,n-1,nums);
        cout<<pos<<endl;
        if(pos==0){
            return binarysearch(0,n-1,target,nums);
        }
        if(nums[0]==target)
            return 0;
        else if(nums[0]>target)
            return binarysearch(pos,n-1,target,nums);
        else
            return binarysearch(0,pos-1,target,nums);
    }
    int findPos(int left,int right,vector<int>&nums){
        if(left>right)
            return -1;
        int mid=(left+right)/2;
        if(nums[left]<=nums[mid]){
            int pos=findPos(mid+1,right,nums);
            if(pos==-1){
                return left;
            }
            if(nums[left]<=nums[pos]){
                return left;
            }
            return pos;
        }
        else{
            int pos=findPos(left,mid-1,nums);
            if(pos==-1){
                return mid;
            }
            if(nums[pos]>nums[mid])
                return mid;
            return pos;
        }
    }
    int binarysearch(int left,int right,int target,vector<int>& nums){
        if(left>right)
            return -1;
        int mid=(left+right)/2;
        if(target==nums[mid]){
            return mid;
        }
        else if(target>nums[mid]){
            return binarysearch(mid+1,right,target,nums);
        }
        else
            return binarysearch(left,mid-1,target,nums);
    }
};
View Code

第二种方法实现(更优):

class Solution {
public:
    int search(vector<int>& nums, int target){
        int left=0;
        int right=nums.size()-1;
        while(left<=right){
            int mid=(left+right)/2;
            if(nums[mid]==target)
                return mid;
            if(nums[left]<nums[mid]){
                if(target<=nums[mid]&&target>=nums[left]){
                    right=mid-1;
                }
                else
                    left=mid+1;
            }
            else if(nums[left]>nums[mid]){
                if(target>=nums[left]||target<=nums[mid]){
                    right=mid-1;
                }
                else
                    left=mid+1;
            }
            else
                left++;
        }
        return -1;
    }
};
原文地址:https://www.cnblogs.com/lilylee/p/5418579.html