Tuesday, 28 July 2015

Find common elements in 3 sorted arrays - C++ code

 // Program to find elements that are common in 3 sorted arrays  
 #include <iostream>  
 using namespace std;  
 // This function finds common elements  
 int searchCommon(int arr1[], int arr2[], int arr3[], int l1, int l2, int l3)  
 {  
   int i=0,j=0,k=0;  
   while(i<l1 && j<l2 && k<l3)  
   {  
   if(arr1[i]==arr2[j] && arr2[j]==arr3[k])  
   {  
     cout<<arr1[i]<<" ";  
     i++;  
     j++;  
     k++;  
   }  
   else if(arr1[i]<arr2[j])  
      {  
         i++;  
      }  
    else if(arr2[j]<arr3[k])  
      {  
         j++;  
      }  
    else  
      k++;  
   }  
 }  
 // main function   
 int main()  
 {  
   int ar1[] = {4,19,33,47,68,79,82,85,100};  
   int ar2[] = {18,19 ,20,33,79, 80, 100};  
   int ar3[] = {1,2,4,33,64,68,79,100,128,139};  
   int l1 = sizeof(ar1)/sizeof(ar1[0]);  
   int l2 = sizeof(ar2)/sizeof(ar2[0]);  
   int l3 = sizeof(ar3)/sizeof(ar3[0]);  
   cout << "Elements that are common : ";  
   searchCommon(ar1, ar2, ar3, l1, l2, l3);  
   return 0;  
 }  

Find common elements in 3 sorted arrays

Find common elements in 3 sorted array


3 arrays are given:

Arr1: 4,19,33,47,68,79,82,85,100
Arr2: 18,19 ,20,33,79, 80, 100
Arr3: 1,2,4,33,64,68,79,100,128,139

Out of all these,
    33,79,100 are the elements that are common in given 3 arrays.

Brute force approach :
Pick first element in arr1 and check if it is present in 2nd and 3rd array also. If yes then print it, otherwise pick second element, then third element and so on.
Time complexity : O(n3 )


An efficient approach :
Algorithm :

Step 1: Initialize i=0,j=0,k=0;
Step 2 :Repeat this step till i<len(arr1) and j<len(arr2) and k <len(arr3)
A)If arr1[i]=arr2[j]=arr3[k] ,print that element as it is the common element and increment i,j,k.
B) Else if arr1[i] < arr2[j] ,then arr1[i] cannot be the common element of 3 arrays as arr2 has already moved ahead. Increment i.
C)  Else if arr2[j]< arr3[k] , then arr2[j] cannot be the common element. Increment j.
D)Else increment k. We will reach to this case when arr1[i] > arr2[j] and arr2[j] > arr3[k] .It means arr3[k] is smallest. So it cannot be the common element.

Time complexity: O(n)
Auxiliary space: O(1)

Monday, 27 July 2015

Traversal in binary tree

Traversals in Binary Tree

Before reading this, please check out our video https://www.youtube.com/watch?v=FFOTq1RcrBE to fully understand what a binary tree actually is.
Now, you must be wondering that how can we print the data of the tree or how can we actually go to each node in the tree. So, traversals are the systematic way through which we can travel to each node in the tree exactly once that too in some systematic behavior.
The linear order, which traverses from beginning to end, is not present in the trees.

The different traversals present for the tree are -
1.    Preorder Traversal
2.    Inorder Traversal
3.    Postorder Traversal
4.    Level Order Traversal

Remember that binary tree is of recursive nature, means that the left and right sub trees of the binary tree root node are themselves the binary trees and this property helps us achieve the traversals using the recursion method.

1.    Pre order Traversal-
     Steps.
i.                   Visit the root
ii.                 Traverse the left sub tree in pre order manner
iii.              Traverse the right sub tree in pre order manner

2.    In order traversal
Steps
i.                   Traverse the Left sub tree in in order fashion
ii.                 Visit the root
iii.              Traverse the right sub tree in in order fashion

3.    Post Order Traversal
Steps
i.                   Traverse the left sub tree in post order fashion
ii.                 Traverse the right sub tree in post order fashion
iii.              Visit the root
We will discuss the level order traversal later.
In all the above three traversals, we can see that the steps involve the traversing the left and right sub trees in some particular fashion, and here at these steps is when we call it recursively.

Recursive implementation of the Traversals

Structure of node of a tree
struct node
{
          int data;
          node *left;    //left child
          node *right;  //right child


}; 











1.    Preorder
void preorder(node *n)         
{
          if(n==NULL) return ;  // if node is NULL or becomes NULL simply return
                                                  //acts as base case
          printf("%d\t", n->data);    // print the root
          preorder(n->left);            // recurse over left sub tree
          preorder(n->right);        //recurse over right sub tree
}



2.    Inorder
void inorder(node * n)
{
          if(n==NULL) return ;
          inorder(n->left);                    // recurse over left first
          printf("%d\t", n->data);   // print node ->data
          inorder(n->right);            // now recurse over right sub tree
}
3.    Postorder
void postorder(node *n)
{
          if(n==NULL) return ;
          postorder(n->left);        
          postorder(n->right);
          printf("%d\t", n->data);
}

Time Complexity – O(n) , n = #nodes in the tree
Space Complexity – O(n) – considering the stack used in the recursion
                                  
Iterative implementations of the Traversals-

1.    Preorder

 void preorderi(node *n)
{
          if(n==NULL)
          return;
          stack<node *>s;                 // make an explicit stack
          s.push(n);                             //push root node into it
         
           while(!s.empty())                 // while stack has nodes
          {
                   node *temp = s.top();               //print parent/node data
                   cout<<temp->data;
                   s.pop();        
//push its left and right children but in opposite order as stack works in LIFO manner
                                   
                   if(temp->right)       
          s.push(temp->right);
                   if(temp->left)
                             s.push(temp->left);
          }
         
}

2.    Inorder
i.                   Create an empty stack
ii.                 push root node and make it the current node
iii.              keep on pushing node till current does not become NULL, right now the topmost element in stack is the first node to be printed in inorder traversal
iv.              now till the stack does not become empty , keep on popping the top print it and move to the popped node’s right  

void inorderi(node *n)
{
          if(n==NULL)
          return;
          stack<node *> s;
          int done =0;
          while(!done)
          {
                   if(n!=NULL)
                   {
                             s.push(n);
                             n=n->left;
                   }
                   else
                   {
                             if(!s.empty())
                             {
                                       n = s.top();
                                      printf("%d \t", n->data);
                                      s.pop();
                                      n=n->right;
                             }
                            
                         else
                             {
                             done =1;   
                             }
                   }
          }
}
3.    Postorder
A little difficult due to non-tail recursion present in it. We simply generate the reverse Postorder and store it in the stack and using the LIFO property we print the correct Postorder traversal.
You may now think that how to generate the reverse Postorder.
Lets try it out on an example –




The Postorder traversal is – 4, 5, 2 , 6 , 7 , 3 ,1

The reverse Postorder Traversal is – 1, 3, 7, 6, 2, 5, 4
We need to get this into the stack. But Question still remains same … How ??

Let us check Preorder Traversal – 1, 2, 4, 5, 3, 6, 7
We know that in preorder first the left subtree is recursed and then right sub tree.
But suppose if we change it to first recurse over right sub tree and then to over left sub tree
Changed preorder traversal – 1, 3, 7, 6, 2, 5, 4
And now you can easily see that this changed preorder and reverse post order traversal we want are the same.
So for iterative Postorder, we go like preorder with two little changes
i.                   Recurse over left first and right later ( remember context of Stack -LIFO)
ii.                 Instead of printing the data, store it in the stack
iii.              At last print the stack 

Two stacks will be needed, one for holding the reverse Postorder and other for iterating over the nodes.

void postorderi(node *n)
{
          if(n==NULL)
          return;
          stack<node *>s1;
          stack<node *>s2;
         
          s1.push(n);
         
          while(!s1.empty())
          {
          node *temp = s1.top();
          s1.pop();                       //popping form s1
          s2.push(temp);          //pushing to s2

          if(temp->left)
          s1.push(temp->left);
                                                          //remember LIFO
          if(temp->right)
          s1.push(temp->right);
          }
          while(!s2.empty())
          {
                   node *t = s2.top();
                   printf("%d\t", t->data);
                   s2.pop();
          }
}


These all are the DFS kind of traversals.
There also exist BFS kind of traversal known as level order traversal.
We will discuss it soon. Till time practice these.


For any queries or problems or future updates, kindly subscribe to our YouTube Channel

Any Queries or updates or any problem in document or the Videos that you may want to discuss you can follow our twitter account - https://twitter.com/Logic_Heap
Or you can join our Facebook group - https://www.facebook.com/groups/logicheap/

Finding closest pair of points

 Algorithm – Finding closest pair of points  
 Technique – using Divide and Conquer strategy   
 Problem – We are given a set of points and we have to find the minimum distance between all the     
           Points.   
 Solution-   
 1.     Naïve Approach – we can loop through all the set of points one by one for each point.   
 Algorithm –   
 float distance( point p1, point p2) //distance between two coordinates   
 {  
      return sqrt((p2.x-p1.x)*(p2.x-p1.x)+(p2.y-p1.y)*(p2.y-p1.y));  
 }   
  float naive(point p[], int n)  // point is the structure having x , y as members(coordinates)  
                            //& n = total number of points available   
 {  
      int i , j ;  
      float min=FLT_MAX;    // defined constant   
      float dist;   
      for(i=0;i<n;i++)          // iterating through each point   
      {  
           for(j=i+1;j<n;j++)   // for each point check its distance from remaining points   
           {  
                dist = distance(p[i], p[j]);    
                if(dist < min)       
                min = dist;   
           }  
      }  
      return min;   
 }  
 Time Complexity – O(n^2)   
 2.     Divide and Conquer Approach – we can better the naïve approach using divide and conquer strategy.   
 Steps –   
        Pre- processing step - Sort the given points according to the x coordinates.   
 1.     Find the middle point.   
 2.     Recursively find the minimum distance in the left and right sub arrays.   
 Understand this step – we can find the minimum distance either on the left side of the mid-point (left sub array) or on the right side (right sub array) or we can find minimum on the points among which one is in the left sub array and another in the right sub array.   
 3.     Among both the minimums (from left and from right), find the minimum, let us call it d.   
 4.     Now comes the important step-   
 We find those points whose distance is less than d from the middle point (found in 1.) in both (left and right) directions   
 As only these could be the candidates for those points whose distance is closest.   
 5.     Sort these points according to the y coordinate  
 6.     Find the minimum among all these points using the naïve approach but it is been proved that inner loop runs at most 6 times.   
 (check this- http://people.csail.mit.edu/indyk/6.838-old/handouts/lec17.pdf) .   
 7.     Now find the minimum between the point found in 7 and d.   
 Time Complexity – time for divide and conquer – 2T(n/2) // as dividing into two sub parts of n/2   
                                                     // size  
 + time for finding the points having distance < d (step 4) – O(n)   
 + time to sort( step 5) – O(nlogn)   
 + step 6 – O(n) because the inner loop runs at most 6 times   
 =) O(nlognlogn)   
 Algorithm -  
 struct point    // point representation   
 {  
      int x, y;   
 };   
 // for sort stl   
 int cmpx(const point& p1, const point& p2)  
 {  
      return (p1.x<p2.x);   
 }  
 int cmpy(const point& p1, const point& p2)  
 {  
      return (p1.y<p2.y);   
 }  
 // step 5 & 6 , strip is the array consisting of “certain points” from left and right sub arrays  
 float stripclosest(point strip[] , int j ,float d)  
 {  
      // d is the min (corresponding to min of naive)  
      // j - #points in strip  
      //5. sort strip acc to y coordinates   
        sort(strip, strip+j, cmpy);   
       int n =j;  
       float dist;   
      //6. find minimum using naive approach .. it takes O(n) not O(n^2) because inner loops   
      // runs atmost 6 times  
      for(int i=0;i<n;i++)  
      {  
 // if distance of points is less than d , only then consider otherwise no need as that pair can never   
 // be closest point(obviously)  
           for(int k=i+1;k<n && abs(strip[k]. y - strip[i].y) < d; k++)  
           {  
                dist = distance(strip[i], strip[k]);   
                if(dist < d)  // if less than the considered minimum  
                {  
                    d = dist;  
                }  
           }  
      }  
      return d ;  
 }  
 float closestutil(point p[], int n)  
 {  
      // Base Case   
       if(n<=3)  
      return naive(p, n);   
      //2. find mid point   
      int mid = n/2;   
       point m = p[mid];   
      //3a. recursively find minimum in left and right sub arrays   
      float dl = closestutil(p, mid);  
      float dr = closestutil(p+mid, n-mid);  
      //3b. find minimum among both  
      float d = minimum(dl, dr);   
      //4. make an array strip and store the point having distance <d from point m  
       point strip[n];  
      int j=0;   
 for(int i=0;i<n;i++)  
      {  
 // take only if the distance of point is less than d from the middle line(point) as only they can be the //candidates for the points having closest distance   
           if(abs(p[i].x-m.x) < d)  
            {  
                strip[j]=p[i];  
                j++;  
           }  
      }  
 // calculating smallest distance in strip and finding minimum among d(min of left and right and min //distance in strip(min if the closest distance is present in subarray crossing some part of left and //right sub array)  
       return minimum(d, stripclosest(strip, j, d, a));   
 }  
 float closest(point p[], int n)  
 {  
      //1. sort the points acc to x coordinate   
        sort(p, p+n, cmpx);  
        return closestutil(p,n);   
 }  
 Before going further do try to code it and if any problem occurs or you have any doubt regarding any thing related to the algorithm or any query please kindly tell us either on our Facebook Group   
 https://www.facebook.com/groups/logicheap/or you can follow our twitter account - https://twitter.com/Logic_Heap  
 For more such algorithms and many more videos and stuff related to algorithms of data structures, kindly subscribe to our YouTube channel -https://www.youtube.com/watch?v=FFOTq1RcrBE  
 Implementation in C++  
 // prints distance and corresponding points also   
 #include <iostream>  
 #include<bits/stdc++.h>  
 using namespace std;  
 struct point  
 {  
      int x, y;   
 };   
 // for qsort stl   
 int cmpqx(const void* u, const void* v)  
 {  
      point *p1 =(point*)u;   
      point *p2= (point*)v;   
      return (p1->x - p2->x);   
 }  
 int cmpqy(const void* u, const void* v)  
 {  
      point *p1 =(point*)u;   
      point *p2= (point*)v;   
      return (p1->y - p2->y);   
 }  
 // for sort stl   
 int cmpx(const point& p1, const point& p2)  
 {  
      return (p1.x<p2.x);   
 }  
 int cmpy(const point& p1, const point& p2)  
 {  
      return (p1.y<p2.y);   
 }  
 float minimum(float i, float j)  
 {  
      return (i<j?i:j);   
 }  
 float distance( point p1, point p2)  
 {  
      return sqrt((p2.x-p1.x)*(p2.x-p1.x)+(p2.y-p1.y)*(p2.y-p1.y));  
 }  
 void printpoint(point a[])  
 {  
      cout<<"\n"<<a[0].x<<" "<<a[0].y;   
      cout<<"\n"<<a[1].x<<" "<<a[1].y;  
 }  
 //O(n^2)  
 float naive(point p[], int n, point a[])  
 {  
      int i , j ;  
      static float t=INT_MAX;   
 // making it static is necessary otherwise suppose that min is found in left subarray and now right //subarray is called and t will not hold the previous min value and calculate the min and point array //will be wrong   
 //I advise you to go and remove static and execute and you will understand the power of static //yourself.  
      float dist;   
      for(i=0;i<n;i++)  
      {  
           for(j=i+1;j<n;j++)  
           {  
                dist = distance(p[i], p[j]);   
                cout<<"\n checking t="<<t;   
                  if(dist < t)  
                {   
                     t = dist;   
                 a[0].x = p[i].x;   
                 a[0].y = p[i].y;   
                 a[1].x = p[j].x;   
                 a[1].y = p[j].y;   
                }  
      }  
      cout<<"\n checking returning t ="<<t;  
      return t;   
 }  
 float stripclosest(point strip[] , int j ,float d, point a[])  
 {  
      // d is the min (corresponding to min of naive)  
      // j - #points in strip  
      //5. sort strip ac to y coordiantes   
      qsort(strip, j , sizeof(point), cmpqy);  
       //sort(strip, strip+j, cmpy); , you can use any but qsort is better   
      int n =j;  
      float dist;   
      //6. find minimum using naive approach .. it takes O(n) not O(n^2) because inner loops   
      // runs atmost 6 times  
      for(int i=0;i<n;i++)  
      {  
           for(int k=i+1;k<n && abs(strip[k]. y - strip[i].y) < d; k++)  
           {  
                dist = distance(strip[i], strip[k]);   
                if(dist < d)  
                {  
                     d = dist;  
                     a[0].x = strip[i].x;   
                     a[0].y = strip[i].y;   
                     a[1].x = strip[k].x;   
                     a[1].y = strip[k].y;  
                }  
           }  
      }  
      return d ;  
 }  
 float closestutil(point p[], int n, point a[])  
 {  
      if(n<=3)  
      return naive(p, n, a);   
      //2. find mid point   
      int mid = n/2;   
      point m = p[mid];   
      //3a. recursively find minimum in left and right sub arrays   
       float dl = closestutil(p, mid,a);  
      float dr = closestutil(p+mid, n-mid,a);   
       //3b. find minimum among both  
      float d = minimum(dl, dr);   
      //4. make an array strip and store the point having distance <d from point m  
      point strip[n];  
      int j=0;   
      for(int i=0;i<n;i++)  
      {  
           if(abs(p[i].x-m.x)<d)  
           {  
                strip[j]=p[i];  
                j++;  
           }  
      }  
      // calculating smallest distance in strip and finding minimum among d(min of left and right)  
      // and min dist in strip(min if the closest distance is present in subarray crossing some part of   
      //left and right sub array)  
      return minimum(d, stripclosest(strip, j, d, a));   
 }  
 float closest(point p[], int n, point a[])  
 {  
      //1. sort the points acc to x coordinate   
       //qsort(p, n, sizeof(point), cmpqx);  
   sort(p, p+n, cmpx);  
       return closestutil(p,n, a);   
 }  
 int main() {  
      point p[] = {{2, 3}, {12, 30}, {40, 50}, {5, 1}, {12, 10}, {3, 4}};  
      point a[2];   
   int n = sizeof(p) / sizeof(p[0]);  
   printf("The smallest distance is %f ", closest(p, n, a));  
   printpoint(a);   
   return 0;  
 }  

Binary Indexed Tree - Code in C++

 // C++ code to demonstrate operations of Binary Index Tree  
 #include <iostream>  
 using namespace std;  
 int getSum(int BITree[], int n, int index)  
 {  
      int sum = 0; // Iniialize result  
      // index in BITree[] is 1 more than the index in arr[]  
      index = index + 1;  
      // Traverse ancestors of BITree[index]  
      while (index>0)  
      {  
           // Add current element of BITree to sum  
           sum += BITree[index];  
           // Move index to parent node  
           index -= index & (-index);  
      }  
      return sum;  
 }  
 // Updates a node in Binary Index Tree (BITree) at given index  
 // in BITree. The given value 'val' is added to BITree[i] and   
 // all of its ancestors in tree.  
 void updateBIT(int *BITree, int n, int index, int val)  
 {  
      // index in BITree[] is 1 more than the index in arr[]  
      index = index + 1;  
      // Traverse all ancestors and add 'val'  
      while (index <= n)  
      {  
      // Add 'val' to current node of BI Tree  
      BITree[index] += val;  
      // Update index to that of parent  
      index += index & (-index);  
      }  
 }  
 // Constructs and returns a Binary Indexed Tree for given  
 // array of size n.  
 int *constructBITree(int arr[], int n)  
 {  
      // Create and initialize BITree[] as 0  
      int *BITree = new int[n+1];  
      for (int i=1; i<=n; i++)  
           BITree[i] = 0;  
      // Store the actual values in BITree[] using update()  
      for (int i=0; i<n; i++)  
           updateBIT(BITree, n, i, arr[i]);  
      return BITree;  
 }  
 // Driver program to test above functions  
 int main()  
 {  
      int *freq,n;                     
      cout<<"enter number of elements: ";  
      cin>>n;  
      freq = new int[n];  
      cout<<"enter the array elements : \n";  
      for(int i=0;i<n;i++)  
       cin>>freq[i];         //check on this to validate above figure {3,5,1,6,7,2,3,4,1,9,13,8};  
      int *BITree = constructBITree(freq, n);  
      //for(int i=1;i<=n;i++)cout<<BITree[i]<<" ";  //uncomment this line to content of BITree[]  
      cout << "Sum of elements in arr[0..5] is "  
           << getSum(BITree, n, 5);  
      // Let use test the update operation  
      int id,value;  
      cout<<"\nenter index and value to be updated : ";  
       cin>>id>>value;  
      updateBIT(BITree, n, id, value); //Update BIT for above change in arr[]  
      cout << "\nSum of elements in arr[0..5] after update is "  
           << getSum(BITree, n, 5);  
      return 0;  
 }  

Binary Indexed Tree ( Fenwick Tree) -Understanding the concept

BINARY INDEXED TREE (Fenwick tree)


MOTIVATION

Let us consider an array arr[0 . . . n-1]. With following two task to perform :- 
1.       Find the sum of first i elements.
2.      Change value of a specified element of the array arr[i] = x where 0 <= i <= n-1.

·         A simple solution is to run a loop from 0 to i-1 and calculate sum of elements. To update a value, simply do arr[i] = x. The first operation takes O(n) time and second operation takes O(1) time.

·         Or, Create another array and store sum from start to i at the i’th index in this array. Sum of a given range can now be calculated in O(1) time, but update operation takes O(n) time now.

Now the question arises can we perform both operation in O(log n) time ?


One can think about  segment tree but implementation using segment tree can be complex and require more memory.so better solution can be produced using binary indexed tree.

Complexities:
·         Time complexity of construction O(nlogn).
·         Time complexity of sum and update operation is O(logn).
·         Space complexity is O(n).

Representation
Binary Indexed Tree is represented as an array. Let the array be BITree[]. Each node of Binary Indexed Tree stores sum of some elements of given array. Size of Binary Indexed Tree is equal to n where n is size of input array. In the below code, we have used size as n+1 for ease of implementation (where 0th indexed is used as a dummy node).initialized all the element of BITree[]={0}.

Operations
1.      Sum(index) : Returns sum of arr[0..index]
2.      update(index, val): Updates BIT for operation arr[index] += val

Algorithms
1.     Sum(index)
1.1.    Initialize sum as 0 and index as index+1.
1.2.    while index is greater than zero .
1.2.1.   Add BITree[index] to sum
1.2.2.    Go to parent of BITree[index].  Parent can be obtained by removing
       the last set bit from index, i.e., index = index - (index & (-index))
1.3.    Return sum


2.      Update(index, val)

       2.1.   Initialize index as index+1.
       2.2.   while index is smaller than or equal to n.
    2.2.1.            Add value to BITree[index]
    2.2.2.            Go to parent of BITree[index].  Parent can be obtained
                 by adding the decimal value of last set bit from index, 
                 i.e., index = index + (index & (-index))
[Note above formula adds decimal value corresponding to last set bit]