Sunday, 14 May 2017

Binary Search and its variants


Binary Search: 
 
 Pre-condition:
         -  Array should be sorted.
    Which problem addressed:
         -  To find if an element exists in that array or not. Return the index where element is present.
   
Time Complexity: O(logN)

int BinarySeaarch(int[] A,int len,int x){
    int start=0; // start index of array A
    int end=len-1; // end index of array A
    while(start<=end){
    int mid = (start+end)/2;
    if(x == A[mid]) return mid;
    else if(x<A[mid]) end =mid-1;
    else start= mid+1;
    }
    return -1; // if not found element in array
   }

Improvements:
The better way to calculate mid is:
   
     mid = start + (end-start)/2

because if start and end are very high number then the sum of two higher value int can result in overflow.

Variances of Binary Search:
1) To find the occurrence of an element in a sorted array with duplicates.

int BinarySearch(int[] A,int len,int x){

int start = 0;
int end =len-1;
// this  stores the index of first or last index of element x depending on code added with //*
int result =-1;
while(start<=end){
int mid  = start +(end-start)/2;
if(a[mid] == x){
result = mid;
//* end = mid-1; // when we want to find first occurrence of element x;
//* start =mid+1; // when we want to find last occurrence of element x;
}else if(a[mid] > x){
end =mid-1;
}else
start =mid+1;
}
return result;
}   

2) How many times sorted array is rotated.
Given a circularly sorted array with no duplicates.

The definition of rotation:
   The number of elements before smallest element is equal to the number of rotations.
   Thus the number of rotations is equal to the  index of smallest element.

   No of rotations =  index of smallest element in array.

   Note the variations applied to binary search:

   int FindPivot(int[] a){
     int len = a.length;
     int lo = 0;
     int hi = len-1;
     if(len == 1) return 0;
     if(len == 2){
         return (a[0]>a[1])?1:0;
     }
     while(lo<=hi){
       int mid = lo +(hi -lo)/2;
      // the pivotal element will be lesser than its previous element
       if(mid == 0 || a[mid]< a[mid-1]){
           return mid;
       }
       if(a[mid] > a[0]){
          lo = mid+1;
       }else{
          // may be element at mid can be minimum thus we set hi to mid
          hi = mid;
       }
     }
     // if array is sorted then first element is minimum
     return a[0];

   }

   Note: This will work only if there is no duplicate elements in array.
   If there are any duplicates then it can't be done in O(logn) .. it can be done linearly O(n).





   

Sunday, 8 April 2012

Find the maximum element in an array which is first increasing and then decreasing

Here we can iterate through array to find maximum element in array by using Brute-Force method.
Its running time would be : O(n).

But still we can do it in a better way with much improved running time complexity i.e O(log(n)).
We can use binary search to solve this problem.

Please find below code in C++.


//Iterative method
int FindMax(vector<int> &aV,int aStart,int aEnd){


int lower=aStart;
int upper = aEnd;
int mid = (upper-lower)/2;
while(lower<=upper){
    if(aV[mid]>aV[mid-1] && aV[mid]>aV[mid+1]){
       cout<<"Found element"<<"\n";
       return aV[mid];
       }
    else if(aV[mid]>aV[mid-1]){
    // Search in second half
    lower = mid+1;
    mid=((upper-lower)/2)+lower;
    cout<<"moving to 2nd part: lower: "<<lower<<" mid:"<<mid<<" upper: "<<upper<<"\n";
    }else {
    // Search in First half
    upper = mid-1;    
    mid = ((upper-lower)/2)+lower;
    cout<<"moving to 1st part: lower: "<<lower<<" mid:"<<mid<<"upper: "<<upper<<"\n";
    }
                     
}
cout<<"Could not find such element"<<"\n";
return -1;  


}

Thursday, 29 March 2012

Wednesday, 28 March 2012

Counting inversion : Complexity O(n*lgn) and in=place sort


#include <cstdlib>
#include <iostream>
#include <vector>
#include<fstream>
#include<iomanip>
#include <cstdio>
#include <cstring>
using namespace std;
#define newData unsigned __int64
/*Inversion : it is set of (i,j) where i<j and a[i]>a[j]
Idea is to create an array from large file with inputs of millions .
Then apply in-place merge sort */

void CreateArrayFromFile(vector<long> &aV,string aFileName)
{
 ifstream file;
 char* fileName = new char[aFileName.size()+1];
 strcpy(fileName,aFileName.c_str());
 file.open(fileName,ifstream::in);
 if(!file)
 {
  cout<<"CreateArrayFromFile:File couldn't open: "<<"\n";
   return ;
  }
long  i=0;
  while(!file.eof()){
  long val;
  file>>val;
//  aV.push_back(val);
  aV[i]=val;
  i++;
  }
  free(fileName);
  file.close();
}
/*The mere is tricky for in-place but it saves O(n) space which is used for merging data in merge function.
*/

newData MergeInSort(vector<long> & aVector,long low, long mid,long high)
{
   
long left=low;
long right=mid+1;
newData count=0;
if(aVector[mid]<aVector[right])
   return 0;
 
while((left<=mid) && (right<=high)) {
// left one smaller then no change:
   if(aVector[left]<aVector[right]){
   left++;
   }else{
   long tmp=aVector[right];
 
   for(long index=right;index>left;index--){
   aVector[index]=aVector[index-1];
   count++;    
   }
   aVector[left]=tmp;
   left++;
   right++;
   mid++;
   }
 }
 
return count;
}

newData InPlaceMergeSort(vector<long> &aVector,long low,long high)
{
// base case
if(low>=high)
   return 0;
 
long mid=(low+high)/2;

newData x= InPlaceMergeSort(aVector,low,mid);
newData y= InPlaceMergeSort(aVector,(mid+1),high);  
newData z= MergeInSort(aVector,low,mid,high);

return (x+y+z);

}


int main(int argc, char *argv[])
{

vector<long> aMainArray(100000);
string file("IntegerArray.txt");
CreateArrayFromFile(aMainArray,file);
long size = aMainArray.size()-1;
cout<<"Size: "<<size<<"\n";
cout<<"Inversion: "<<InPlaceMergeSort(aMainArray,0,size)<<"\n";

  system("PAUSE");
  return EXIT_SUCCESS;
}

Ans : 2407905288




Sunday, 19 February 2012

Insertion-Sort with running time O(n lg(n))

Insertion Sort :
Insertions sort , sorts the elements in place in an array with running time O(n2).
Below is code of insertion sort with running time O(n2) :


void InsertionSort(vector<int>& aV)
{
int size = aV.size();
for(int i=1;i<size;i++)
 {
  for(int j=0;j<i;j++)
   {
     // Places element i in correct and sorted sub-array 0...(i-1)
     if(aV[i]<aV[j])
     {
      int temp = aV[i]; 
      aV[i]=aV[j];
      aV[j]=temp;
     }
   }
 }
}

Here we can play with above code to improve running time to O(n lg(n)) by using Binary Search.
Instead of inner loop in code mentioned above , Binary Search can be used to search for place of swap and then sort remaining array so that sub-array ( from 0 to (i-1) ) will be sorted.

Please find code below :
/*Insertion Sort with Binary Search Running time : O(n lg(n)) */
void BinarySearchAndSwap(vector<int> &aV,int aIndexTillSorted,int aIndexToSearch)
{
int low =0;
int high =  aIndexTillSorted;

    while(low<=high)
         {
          int mid = (low+high)/2;
          if(aV[mid]>aV[aIndexToSearch])
          {
           if(aV[mid-1]>aV[aIndexToSearch])
              high = mid-1;
           else // swap mid and aIndexToSearch
               {
                int temp = aV[aIndexToSearch];
                aV[aIndexToSearch] = aV[mid];
                aV[mid]= temp;
                // To sort remaining part of array 
                  low= mid+1;
               }   
          
          }else if(aV[mid]<aV[aIndexToSearch])
          {
           if(aV[mid +1]< aV[aIndexToSearch])
               low = mid+2;
           else{ // Swap mid +1 with aIndexToSearch
                int temp = aV[aIndexToSearch];
                aV[aIndexToSearch] = aV[mid +1];
                aV[mid+1] = temp;
                // To sort remaining part of array 
                low= mid+2;         
                }    
          }        
             
             
          }

}
void InsertionSortWithbinarySearch(vector<int> &aV)
{
int size = aV.size();

    for(int i=1;i<size;i++)
    {
     BinarySearchAndSwap(aV,i-1,i);
    }
}



Wednesday, 15 June 2011

Khamma Ghani Sa

To all my friends "Khamma Ghani Sa"...

I was born in Jodhpur, the Sun City. It’s famous for its delicious food (that’s all I remember about the heritage city. HENCE PROVED. I am a big foodie). I did my schooling from Jodhpur and graduation from Jaipur. Finally came to my Karma Bhoomi Bangalore. “Karma Bhoomi” because most of the time I stay in office( My wife will not like this I know ). No regrets after all I get paid for it.

Born in Marwar and belong to a traditional yet well educated Marwari family. Obviously, I am supposed to understand and speak Marwari very well.But yesterday when I was talking to my father-in-law over phone.Oh ! before that I want to say he has a very good sense of humor which I like most in him.(It is not just to please my wife ).Lets continue ,  he greeted me with  most of the times heard words "Khamma Ghani Sa" and I replied with "Ghani Ghani Kamma Sa" .

But it left a question in my mind .. What is the actual meaning of this "Khamma Ghani Sa" ?

Today in office , after I signed in to gtalk ... I saw couple of Jodhpuri friends online . Discussed with them about these mystery word ... after discussion and couple of google searches found out its meaning .

Khamma - "Daya or Meeharbani or Mafi" basically forgiveness
Ghani      - "Bahut "
and Sa is use to give respect .
This is basically used to greet elders in Marwari Language .

Next time onwards I'll  make sure that before my father-in-law greet me with these no-more mystery words I will greet him with "Khamma Ghani Sa" .

Thanks to my dear friends Ankur Acharya , Rakesh Harsh, Dheeraj Tanwar with whome i discussed on these words.

A very special thanks to my beautiful and lovable wife for playing the role of editor :).