[LeetCode]33. Search in Rotated Sorted Array

来源:互联网 发布:linux挂载ntfs分区 编辑:程序博客网 时间:2024/05/02 04:43

33. Search in Rotated Sorted Array

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.

分析

题中给出的序列是由两个已经排序的序列合并而成的,并且后面的有序序列的所有数都是比第一个序列的首元素小,这里有两种思路:

  1. 找到这个pivot所在的位置,然后用target和这个pivot所在元素比较,找出target在前半段还是后半段范围内,然后在这个找到的范围内用二分法查找

  2. 直接使用二分查找法,只是这里的二分法稍微复杂了点。
    如果nums[first] <= nums[mid],那么firstmid之间是有序的,这个时候判断target是否在first...mid之间,在的话last=mid,如果不在,那肯定在mid+1...last之间,first=mid+1;
    否则nums[first] > nums[mid],那么pivot在first…mid之间,即mid…last之间是有序的,这个时候判断target是否在mid...last之间,在的话first=mid+1,如果不在,那肯定在first...mid之间,last=mid

源码

方法1:先找pivot,然后用二分法

    int binarySearch(vector<int>& nums, int start, int end, int target) {        // 递归二分法        // if((end - start) == 1 || end == start) {        //     if(nums[start] == target) return start;        //     else if(nums[end] == target) return end;        //     else return -1;        // }        // int middle = (end + start) / 2;        // if(nums[middle] == target) return middle;        // else if(nums[middle] < target) start = middle;        // else end = middle;        // return binarySearch(nums,start,end,target);        //循环二分法        int middle, low = start, high = end;        int ret = -1;        while(low <= high) {            middle = (low + high) / 2;            if(nums[middle] == target) {                ret = middle;                break;            } else if(nums[middle] < target) {                low = middle + 1;            } else {                high = middle - 1;            }        }        return ret;    }    //寻找pivot    int indexOfPivot(vector<int>& nums) {        int index = -1;        if(nums.size() < 2) return index;        for(int i = 1; i < nums.size(); i++) {            if(nums[i] < nums[i-1]) {//当前数比前一数小,因为没有重复数,所以可以直接判断                index = i;                break;            }        }        return index;    }    int search(vector<int>& nums, int target) {        if(nums.size() == 0) return -1;        int pivot = indexOfPivot(nums);        if(pivot == -1) return binarySearch(nums, 0, nums.size() - 1, target);//没有pivot,直接二分法        else if(nums[pivot] <= target && target <= nums[nums.size()-1]) return binarySearch(nums,pivot,nums.size() - 1, target);        else if(nums[pivot - 1] >= target) return binarySearch(nums,0,pivot - 1, target);        else return -1;    }

方法二:直接二分法

    int search(const vector<int>& nums, int target) {        int first = 0, last = nums.size();        while (first != last) {            const int mid = first + (last - first) / 2;            if (nums[mid] == target)                return mid;            if (nums[first] <= nums[mid]) { // 因为序列没有重复元素,这里等号不需要也可以; first...mid之间都是顺序的                if (nums[first] <= target && target < nums[mid])                    last = mid;                else                    first = mid + 1;            } else { // nums[first] > nums[mid] 说明序列扭转点发生在first...mid之间,但是mid之后的数是顺序的                if (nums[mid] < target && target <= nums[last-1])                    first = mid + 1;                else                    last = mid;            }        }        return -1;    }
0 0
原创粉丝点击