Leetcode-33.Search in Rotated Sorted Array.

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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值