33. Search in Rotated Sorted Array

1. Description

You are given an integer array nums sorted in ascending order, and an integer target.
Suppose that nums 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]).
If target is found in the array return its index, otherwise, return -1.

2. Example

Example 1:
Input: nums = [4,5,6,7,0,1,2], target = 0
Output: 4

Example 2:
Input: nums = [4,5,6,7,0,1,2], target = 3
Output: -1

Example 3:
Input: nums = [1], target = 0
Output: -1

3. Constraints

  • 1 <= nums.length <= 5000
  • $-10^4$ <= nums[i] <= $10^4$
  • All values of nums are unique.
  • nums is guranteed to be rotated at some pivot.
  • $-10^4$ <= target <= $10^4$

4. Solutions

My Accepted Solution

n = i_nums.size()
Time complexity: O($lg_2n$)
Space complexity: O(1)

class Solution 
{
private:
    int binarySearch(const vector<int> &i_nums, int left, int right, int target) // right is the index after the last valid item, like i_nums.end() 
    {
        for(int middle = 0; left < right; )
        {
            middle = (left+right) / 2;
            
            if(i_nums[middle] == target)
                return middle;
            else if(i_nums[middle] < target)
                left = middle + 1;
            else 
                right = middle;
        }
        
        return -1;
    }
    
    int findLastRotatedSubarrayIndex(const vector<int> &i_nums)
    {
        for(int left = 0, right = i_nums.size(), middle = 0; left < right; )
        {
            middle = (left+right) / 2;
            
            if(i_nums[middle] > i_nums.back() && i_nums[middle] > i_nums[middle+1])
                return middle;
            else if(i_nums[middle] > i_nums.back())
                left = middle + 1;
            else
                right = middle;
        }
        
        return -1; // meaningless, for compile check
    }
public:
    // int search(vector<int>& nums, int target)
    int search(const vector<int> &i_nums, int target) 
    {
        // find the index of the last rotated subarray
        int lastRotatedIndex = findLastRotatedSubarrayIndex(i_nums);

        return (target <= i_nums.back() ? 
               binarySearch(i_nums, lastRotatedIndex+1, i_nums.size(), target)
               : binarySearch(i_nums, 0, lastRotatedIndex+1, target)
               );
    }
};

4.1 Binary Search - Merge Two Processes

n = i_nums.size()
Time complexity: O($lg_2n$)
Space complexity: O(1)

class Solution 
{
public:
    // int search(vector<int>& nums, int target)
    int search(const vector<int> &i_nums, int target) 
    {
        for(int left = 0, right = i_nums.size() - 1; left <= right; )
        {
            int middle = (left+right) / 2;
            
            if(i_nums[middle] == target) return middle;
            
            if(i_nums[middle] < i_nums[right])
            {
                if(i_nums[middle] < target && i_nums[right] >= target) 
                    left = middle + 1;
                else 
                    right = middle - 1;
            }
            else
            {
                if(i_nums[left] <= target && i_nums[middle] > target) 
                    right = middle - 1;
                else 
                    left = middle + 1;
            }
        } 
        
        return -1;
    }
};
comments powered by Disqus