• [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;
        }
    };
  • 相关阅读:
    9
    8
    7
    6
    5
    第四周
    作业14-数据库
    作业13-网络
    作业12-流与文件
    作业11-多线程
  • 原文地址:https://www.cnblogs.com/lilylee/p/5418579.html
Copyright © 2020-2023  润新知