Sunday, 13 January 2013

Queue with push_rear(), pop_front() and get_min() in constant time


/*
This is a very good question. It took me good 2-3 hours to implement this.
push at rear and pop from front are O(1) operations, but to get minimum value is a really tough ask.
To implement this I used a separate queue, which is updated on push and pop operation to hold minimum value.
I have tested it in most scenarios but not all, if you find any scenario in which it will not work do let me know.
*/
#include<iostream.h>
#include<conio.h>
#include<process.h>
class Node
{
public:
      int data;
      Node *next;
       Node()
       {
                  next = NULL;
       }
       void initialiseNode(int val, Node *newNext)
       {
            data = val;
            next = newNext;
       }
};

class minimumQueue
{
public:
       Node *minFront;
       Node *minRear;
       minimumQueue()
       {
                 minFront = NULL;
                 minRear = NULL;
       }
     
       void minQueuePushRear(int val)
       {
            Node *newNode = new Node;
            newNode->data =val;
            if(minRear == NULL && minFront == NULL)
            {
                       minRear = newNode;
                       minFront = newNode;
            }
            else
            {
                minRear->next = newNode;
                minRear = minRear->next;
            }
       }
     
       void minQueuePopFront()
       {
            Node *ptr = minFront;
            if(minFront == minRear)
            {
                              minFront = NULL;
                              minRear = NULL;
            }
            else
            {
                minFront = minFront-> next;
            }
            delete ptr;
       }
};


class Queue
{
      Node *front ;
      Node *rear ;
      minimumQueue minQueue;
public:
       Queue()
       {
              front = NULL;
              rear = NULL;
       }
       bool isEmpty()
       {
            if(front == NULL && rear == NULL)
            {
                return true;
            }
            else
            {
                return false;
            }
       }
     
       void push_rear(int val)
       {
            Node *newNode = new Node;
            newNode->data = val;
            if(isEmpty())
            {
                front = newNode;
                rear = newNode;
                minQueue.minQueuePushRear(val);  
            }
            else
            {
                rear->next = newNode;
                rear = rear->next;
                if(minQueue.minRear->data > val)
                {
                                minQueue.minRear->data = val;
                }
                else
                {
                    minQueue.minQueuePushRear(val);
                }
                //this is later on added code
                if(val < minQueue.minFront->data)
                       minQueue.minFront->data = val;
            }
       }
       void pop_front()
       {
            Node *deleteFront = front;
            int val = front->data;
            if(front == rear)
            {
                front = NULL;
                rear = NULL;
            }
            else
            {
                front = front->next;
                if(val == minQueue.minFront->data)
                {
                    minQueue.minQueuePopFront();
                }
            }
            delete deleteFront;
       }
     
       void display()
       {
           for(Node *ptr = front; ptr != rear; ptr = ptr->next)
                    cout<<" "<<ptr->data;
           cout<<" "<<rear->data;
       }
     
       int get_min()
       {
           int value;
           if(minQueue.minFront == NULL)
                     value = -1;
           else if(minQueue.minFront->data > minQueue.minRear->data)
                                      value = minQueue.minRear->data;
           else
               value = minQueue.minFront->data;
           return value;
       }
     
     
};

int main()
{
    Queue q ;
    int choice,value,min;
    while(1)
    {
        system("CLS");
        cout<<"1. PUSH REAR\n2. POP FRONT\n3. GET MIN\n4. DISPLAY\n5. EXIT\n\nchoice?";
        cin>>choice;
        switch(choice)
        {
            case 1:
                 cout<<"Enter Value";
                 cin>>value;
                 q.push_rear(value);
                 break;
            case 2:
                 q.pop_front();
                 break;
            case 3:
                 min = q.get_min();
                 cout<<"\n Min is : "<<min;
                 getch();
                 break;
            case 4:
                 q.display();
                 getch();
                 break;
            case 5:
                 exit(0);
            default:
                    cout<<"Invalid Input";
        }
    }
}

Find all the sets of length k in an array such that the sum of all the elements of set is equal to a given number S.

/*
    *  Array a[]      = Array to hold elements in set.
    *  howManyNoInSet = Size of set (k).
    *  size           = Elements in input array.
    *  sum            = Total sum of elements included in resulting set.
    *  spaceLeft      = Number of elements included in set currently.
    *  pos            = Index in input array.
    *  Total          = given number S.
    *  
    *  Eg.  Input : arr[] ={1,0,-1,2,-2,3}
    *  k = 3
    *  S = 0
    *  Sets :
    *  (1,0,-1)
    *  (0,2,-2)
    *         (-1,-2,3)
*/
 
/*
    *  RECURSIVE ALGORITHM
    *  1. if pos (current index of input array) is greater than equal to size of array 
    *     then return as it is not a valid element of input array.
    *  2. if set contains k(howManyNoInSet) elements and sum of these k elements = given Number S.
    *     i.e. if ( spaceLeft == 0 && sum == 0) then 
    *           we have found a solution.
    *  3. Else the solution doesn't matches our criteria and is discarded.
    *  4. Now, make 2 recursive calls:
    *   a. Not Including the current element in set. 
    *      RecurssiveSumCheck(pos+1, spaceLeft, sum)
    *   b. Including the current element in set.
    *      Since current element is included in set spaceLeft dicreases by 1 and sum also dicreases by value of current element.
    *      RecurssiveSumCheck(pos+1, spaceLeft-1, sum-arr[pos+1]);
*/
 
 
 
 
#include<iostream>
using namespace std;
int arr[]={-1,0,1,2,-2,4,-4,5,-5};
int size = sizeof(arr)/sizeof(arr[0]);
int *a;
int startIndex = -1, howManyNoInSet =3, Total = 0;
 
void RecurssiveSumCheck(int pos, int spaceLeft , int sum)
{
     if(pos >= size)
            return ;
     if(spaceLeft == 0 && sum == 0)
     {
          cout<<endl;
          for(int i =0;i<howManyNoInSet ; i++)
                                cout<<" "<<a[i];
          return ;
     }
     if(spaceLeft == 0 && sum !=0 )
        return;
     RecurssiveSumCheck(pos+1, spaceLeft, sum);
     a[howManyNoInSet-spaceLeft]=arr[pos+1];
     RecurssiveSumCheck(pos+1, spaceLeft-1, sum+arr[pos+1]);        
}
 
int main()
{
    a = new int[howManyNoInSet];
    RecurssiveSumCheck(startIndex,howManyNoInSet,Total);
}

Write a program to check whether a linked list is palindromic linked list O(n) complexity. Do not use extra space.

/*
1.Find out the middle of the linked list, the middle can be found out by using two pointers slow and fast, slow is incremented by 1 and the fast by 2, when the fast reaches the end the slow will be at the middle.
The fast pointer stops when either fast next is NULL or the next of next is NULL. When the next is NULL then the list is odd and when the next of next is NULL the list os even numbered. 
2. Assign middleNode pointer to slow pointer.
  for odd linked list assign secondHalf pointer to middleNode->next
  for even linked list assign secondHalf pointer to middleNode->next->next
3. Now recurse on linked list until middleNode is reached.
4. After firstHalf pointer reaches middleNode pointer(base case) we compare secondHalf and firstHalf. 
Three important function
getMiddleNode()
recursivePalindromeCheck()
checkPalindrome()
check
*/
#include<iostream.h>
#include<conio.h>

class node
{
public:
       int data;
       node *next;
       node()
       {
             next = NULL;
             data = 0;
       }
};

class linkedList
{
public:
    node *start;
    node *middleNode;
    node *secondHalf;
    bool isPalindrome;
    linkedList()
    {
        start = NULL;
        middleNode = NULL;
        secondHalf = NULL;
        isPalindrome = true;
    }
    
    void insertInFront(int val)
    {
         node *newNode = new node;
         newNode->data = val;
         if(start == NULL)
         {
                  start=newNode;
         }
         else
         {
             newNode->next = start;
             start = newNode;
         }
    }
    
    void display()
    {
         node *ptr = start;
         while(ptr != NULL)
         {
                   cout<<ptr->data<<" -> ";
                   ptr = ptr->next;
         }
    }
    
    void getMiddleNode()
    {
      node *slow = start,*fast = start->next;
      while(fast->next != NULL && fast->next->next != NULL)
      {
                       fast = fast->next->next;
                       slow = slow->next;
      }
      if(fast->next == NULL)
                    secondHalf = slow->next;
      else
                    secondHalf = slow->next->next;
      middleNode = slow;
    }
          
    
    bool checkPalindrome()
    {
      getMiddleNode();
      cout<<"\nmiddleNode = "<<middleNode->data<<"\n";
      cout<<"\nSecondHalfNode = "<<secondHalf->data<<"\n";
      getch();
      recursivePalindromeCheck(start);
      if(isPalindrome)
                       cout<<"PALINDROMIC LINKED LIST";
      else
          cout<<"NON PALINDROMIC LINKED LIST";
      
    }
    
    void recursivePalindromeCheck(node *firstHalf)
    {
      if( firstHalf == middleNode )
          ;
      else
      {
          recursivePalindromeCheck(firstHalf->next);
          
      }
      if( firstHalf->data == secondHalf->data)
              secondHalf = secondHalf->next;
          else
              isPalindrome = false;
    }
};

int main()
{
    linkedList list;
    int choice,val;
    while(1)
    {
        system("CLS");
        cout<<"1. Insert in Front\n2. Display\n3. Ispalindrome?\n4. Exit\n\nchoice? ";
        cin>>choice;
        switch(choice)
        {
            case 1:
                 cout<<"\nEnter Value : ";
                 cin>>val;
                 list.insertInFront(val);
                 break;
            case 2:
                 list.display();
                 getch();
                 break;
            case 3:
                 list.checkPalindrome();
                 getch();
                 break;
            case 4:
                 exit(0);
            defaule:
                    cout<<"Invalid Input";
        }
    }
}
                               

A sorted array is rotated right by some number. Find the smallest element in O(log n).


/*
print the smallest element in rotated array.
*/

#include<iostream.h>
int main()
{
    int arr[]={6,7,8,9,10,11,12,13,14,1,2,3,4,5};
    int n = sizeof(arr)/sizeof(arr[0]);
    int start =0, end = n-1, mid = (end+start)/2;
    while(start<mid && mid<end)
    {
        if( arr[mid] < arr[mid-1])
        {
            cout<<arr[mid];
            break;
        }
        else if( arr[start] > arr[mid] )
        {
             end = mid;
        }
        else
            start=mid;
        mid = (end+start)/2;
    }
}

Remove all occurrences of a string from another string.


/*
Pattern:google
Input : I googled on google about google
Output: I d on  about
*/
#include<iostream.h>
#include<conio.h>
#include<string.h>

using namespace std;

int main()
{
    string masterString ="I googled on google about google.";
    string pattern="google";
    int count =0;
    int masterLen = masterString.length();
    int patternLen = pattern.length();
    for(int i =0 ; i<= masterLen ; i++)
    {
        if(masterString.substr(i,patternLen) == pattern)
        {
            count++;
            i = i+patternLen;
        }
        if(count>0)
        {
            if(i < masterLen)
                masterString[i-count*patternLen] = masterString[i];
        }
    }
    cout<<masterString.substr(0,masterLen-count*patternLen);
    getch();
}

Reverse words of a string without using extra space.

/*
Input: This is a test string
Output: string test a is This
*/
#include<iostream.h>
#include<string.h>

int reverse(char *str,int s,int e)
{
    char temp;
    for(int i=0 ; i<(e-s+1)/2 ; i++)
    {
        temp = str[i+s];
        str[i+s]=str[e-i];
        str[e-i]=temp;
    }
}

int main()
{
    char str[]="This is a test string";
    int len = strlen(str);
    int start=0,end;
    
    reverse(str,0,len-1);
    for(int i=0; i<=len ; i++)
    {
        if(str[i]==' ' || str[i]=='\0')
        {
            end = i-1;
            reverse(str,start,end);
            start = i+1;
        }
    }
    cout<<str;
}