【LeetCode】Search in Rotated Sorted Array旋转数组问题总结

来源:互联网 发布:移动网络电话号码 编辑:程序博客网 时间:2024/05/16 00:26

问题1. 数组中没有重复的数字

/************************************************************************
*
* 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.
*
************************************************************************/

此题常规的解法为O(N),即遍历一遍数组,找到与target相同的索引,但是这种做法明显没有利用给的条件去做题。

二分的方法主要分两步:

  1. 找到旋转数组中最小值的索引,这一点很巧妙,可以用二分的方法去寻找这个最小值的索引,代码如下:
 while (low<high) {            int mid=(low+high)>>1;            if (nums[mid]>nums[high]) low=mid+1;            else high=mid;        }

2.找到最小值点的索引后,我们就知道了他的旋转点再哪里,即
rot=low旋转了rot个长度。
例如: 1 3 5 7 9 旋转成 5 7 9 1 3,则旋转了3个长度。
那么在我们再一次用普通的二分查找mid时,实际上我们是查找旋转数组中的realmid=(mid+rot)%length因此二分搞定。

综上所述,完整AC代码如下:

class Solution {public:    int search(vector<int>& nums, int target) {        int n=nums.size();        int low=0,high=n-1;        //find the smallest index        while (low<high) {            int mid=(low+high)>>1;            if (nums[mid]>nums[high]) low=mid+1;            else high=mid;        }        int rot=low;low=0,high=n-1;        //usualy binary search        while (low<=high) {            int mid=(low+high)>>1;            int realmid=(mid+rot)%n;            if (nums[realmid]==target) return realmid;            else if (nums[realmid]>target) high=mid-1;            else low=mid+1;        }        return -1;    }};

问题2. 数组中有重复数字

/********************************************************************************** * * Follow up for "Search in Rotated Sorted Array":* What if duplicates are allowed?* * Would this affect the run-time complexity? How and why?* * Write a function to determine if a given target is in the array.*               **********************************************************************************/
class Solution {public:    bool search(vector<int>& nums, int target) {        int left = 0, right =  nums.size()-1, mid;        while(left<=right) {            mid = (left + right) >> 1;            if(nums[mid] == target) return true;            // the only difference from the first one, trickly case, just updat left and right            if( (nums[left] == nums[mid]) && (nums[right] == nums[mid]) ) {++left; --right;}            else if(nums[left] <= nums[mid]) {                if( (nums[left]<=target) && (nums[mid] > target) ) right = mid-1;                else left = mid + 1;             }            else {                if((nums[mid] < target) &&  (nums[right] >= target) ) left = mid+1;                else right = mid-1;            }        }        return false;    }};
0 0