Leetcode-33.Search in Rotated Sorted Array.

来源:互联网 发布:网络教育专科报名条件 编辑:程序博客网 时间:2024/05/02 02:53

Problem description:
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.


Analysis:
Idea: We could use the binary search to find the SMALLEST num in the array. Then we could use usual binary search and accounting for rotation offset.
O(logn) solution :

Codes:
For the first binary search, we have to compare the middle element with nums[r] to find the smallest num.

int search(vector<int>& nums, int target)   {    int n = nums.size();    int l = 0, r = n - 1;    while (l < r)     {        int m = l + ((r - l ) >> 1);        if (nums[m] >= nums[r]) l = m + 1;        else if (nums[m] < nums[r]) r = m;    }    int offset = n - l;    //int offset1 = l;  //    cout<<offset<<endl;    l = 0; r = n;    while (l < r)    {        int m = l + ((r - l ) >> 1);        int newm = (m - offset + n) % n;        // newm = (m + offset) % n;        if (nums[newm] < target) l = m + 1;        else if (nums[newm] > target) r = m;        else return newm;    }  return  - 1;  }

Another solution:
mid = (lo & hi) + ((lo ^ hi) >> 1): the first part accounts for the carry bit and the second part accounts for the sum bit. Since we need to divide by 2, so the sum bit shifts to right by 1 and the carry bit simply does not shift (originally it needs to shift to left by 1).

int search(vector<int>& nums, int target)   {    int l = 0, r = nums.size() - 1;    while (l <= r)    {        int m = (l & r) + ((l ^ r) >> 1);//        if (nums[m] == target) return m;        if (nums[m] >= nums[l])        {            if (target >= nums[l] && target <= nums[m]) // target in (nums[l],nums[m]);                 r = m - 1;            else                 l = m + 1;        }        else        {            if (target >= nums[m] && target <= nums[r])//target in (nums[m],nums[r]);                l = m + 1;            else                 r = m - 1;        }    }    return  -1;  }

Follow up:
What if duplicates are allowed.

Analysis:
Consider this case:
Sorted Array : 1111115, which rotated to 1151111.
When l = 0, m = 3, target = 5,
nums[l] == nums[m] holds true. so there only two possibilities:
1. All number between nums[l] and nums[r] are all ‘1’;
2. different numbers (including target) may exist between nums[l] and nums[r].
As we cannot determine which of the above is true, the best we can do is to move l one step to the right and repeat the process. So the worst case runs in O(n).

bool search(int A[], int n, int key) {    int l = 0, r = n - 1;    while (l <= r) {        int m = l + (r - l)/2;        if (A[m] == key) return true; //return m in Search in Rotated Array I        if (A[l] < A[m]) { //left half is sorted            if (A[l] <= key && key < A[m])                r = m - 1;            else                l = m + 1;        } else if (A[l] > A[m]) { //right half is sorted            if (A[m] < key && key <= A[r])                l = m + 1;            else                r = m - 1;        } else l++; // skip the dups    }    return false;}
0 0
原创粉丝点击