Skip to main content

Rotated Array(Modified Binary Search)

 

A modified binary search is an algorithm that can be used to find an element in a sorted array by using a different base or condition than the standard binary search. It is an extension of the bitwise binary search and has a similar running time of O(log N) .

There are different ways to modify the binary search algorithm, such as using a different number base, finding the minimum element in a rotated and sorted array, or comparing the input element with the first, last and middle elements of the array. Today we will look at rotated array problems.

A rotated array is an array that is sorted in ascending order but shifted to the right by some unknown number of positions. For example, [0,1,2,4,5,6,7] is a sorted array and [4,5,6,7,0,1,2] is a rotated array with 4 positions shifted. A rotated array can also be seen as two sorted subarrays concatenated together. For example, [4,5,6,7] and [0,1,2] are two sorted subarrays that form the rotated array [4,5,6,7,0,1,2].

There are two very popular rotated array problem in leetcode. Which are given below:

153. Find Minimum in Rotated Sorted Array:

Suppose an array of length n sorted in ascending order is rotated between 1 and n times. For example, the array nums = [0,1,2,4,5,6,7] might become:
  • [4,5,6,7,0,1,2] if it was rotated 4 times.
  • [0,1,2,4,5,6,7] if it was rotated 7 times.
We have to find out, the minimum number in the rotated array. If we use brute force technique and search through the whole array, we can easily find out the solution. But it will take O(n) time. Which is very time consuming. So, we have to find out more efficient way to solve this. If we look at question we have something like a sorted array, so we can apply binary search. But for this we have change some of the condition.

class Solution {
public:
    int findMin(vector<int>& nums) {
       int st=0,en=nums.size()-1;
       if(nums[st]<=nums[en]) return nums[st];
       int res;
       while(st<=en){
           int mid = st + (en-st)/2;
           if(nums[mid]>nums[mid+1]) return nums[mid+1];
           else if(nums[mid]<nums[mid-1]) return nums[mid];
           else if(nums[st]<=nums[mid]) st = mid+1;
           else if(nums[mid]<=nums[en]) en = mid-1;
       }
       return -1;
    }
};

If we look very closely to the array, we can see the minimum number in the array is smaller than it previous and next element. So, we find out the mid element in binary search. If it satisfied the condition we can return the number.

If it doesn't, we have to choose a right or left side. Where we can continue our searching. So, we simply choose the side where it isn't sorted and continue the searching.

Time complexity: O(logn)

Problem Link: Find Minimum in Rotated Sorted Array - LeetCode

33. Search in Rotated Sorted Array:

In this problem, we have to find a element in the rotated array and return it's index. If we don't find the element in array we simply return -1.

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int st=0,en=nums.size()-1;
        while(st<=en){
            int mid = st + (en-st)/2;
            if(nums[mid]==target) return mid;
            else if(nums[mid]>=nums[st]){
                if((target>=nums[st]) && (target<=nums[mid])) en = mid-1;
                else st = mid+1;
            }
            else{
                if(target>=nums[mid] && target<=nums[en]) st = mid+1;
                else en = mid-1;
            }
        }
        return -1;
    }
};

In this solution, we divide the array into two part and search through the left or right. First, we find out the mid, if the element is in the middle point return the index. Else we have to look at the left or right side. If the element in the right side, we continue searching in right side. Otherwise in the left side.

Time complexity: O(logn)

Problem Link: Search in Rotated Sorted Array - LeetCode

Comments

Popular posts from this blog

Easiest way to find out which power of number is big?

If you are given two number with its power and told you which number is big. How do you calculate it. For, instance you would say binary exponentiation technique. But this is bit harder when the test case number is bigger. There is also an easy way to solve this problem. Suppose you are given 2^18 and 6^12. Then, you just take logarithm in both numbers. Then it will become 18*log2 and 12*log6. Logarithm function will break this number and make it a little number. which can be compare easily. But for this you have to Double number type, or you will get an error message. Problem:  Problem - 987B - Codeforces Code: void solve() {    ll a,b;    cin>>a>>b;    double num1 = b*log(a);    double num2 = a*log(b);    if(num1==num2) cout<<'='<<endl;    else if(num1>num2) cout<<'>'<<endl;    else cout<<'<'<<endl; }

Find out all divisor in efficient way!

1. Brute force approach:   In this process, we use a for loop and iterate the whole 1 to n number. Then, we find out all the divisors by one by one. It is not a optimal solution for this problem. Because, it will take O(n) time to find out all divisors. int main() {     optimize();     ll n;     cin>>n;     for(ll i=1; i<=n; i++)     {         if(n%2==0) cout<<i<<" ";     }     cout<<endl;     return 0; } Time complexity: O(n) 2. SQRT approach:   In this process, we only iterate in the loop by half of the numbers. Because, if we see we don't need to go through whole n numbers. int main() {     optimize();     ll n;     cin>>n;     for(ll i=1; i * i<=n; i++)     {         if(n%2==0) cout<<i<<" "<<n/i<<endl;     }     return 0; } Time Complexity: O(sqrt(n))       

Binary Search Problems!

1. Find the first and last position of a element in sorted array:   In this problem, they will gave us a sorted array and a number. We have to find out the first and last position of that element. if the target is not found, we have to return [-1,-1]. We have to solve this problem in O(log_n) time. So, we have to use binary search algorithm. Input:      nums =  [5 ,7 ,7, 8, 9, 10], target=7 Output:   [1, 2] Solution: class Solution { public:     vector < int > searchRange ( vector < int > & nums , int target ) {         int st= 0 ,en= nums . size ()- 1 ;         int index1=- 1 ,index2=- 1 ;         while (st<=en){             int mid = st + (en-st)/ 2 ;             if ( nums [mid]>target) en = mid- 1 ;             else if ( nums [mid]<target) st = mid+ 1 ;             else if ( nums [mid]==target){                 index1 = mid;                 en = mid- 1 ;             }         }         int st1= 0 ,en1= nums . size ()- 1 ;         while (st1<=en1