Sunday, 30 July 2017

CTCI Challange, DAY 6

Day 6:-

Program Statement:- A Tale of Two Stacks


On Paper:-




public static class MyQueue<T> {
        Stack<T> stackNewestOnTop = new Stack<>();
        Stack<T> stackOldestOnTop = new Stack<>();

        public void enqueue(T value) { // Push onto newest stack
            stackNewestOnTop.push(value);
        }

        public void dequeueOrPeek(int operation) {
            if (stackOldestOnTop.isEmpty()) {
                while (!stackNewestOnTop.isEmpty()) {
                    stackOldestOnTop.push(stackNewestOnTop.pop());
                }
            }
            if (operation == 2)
                stackOldestOnTop.pop();
            else
                System.out.println(stackOldestOnTop.peek());
        }
    }

    public static void main(String[] args) {
        MyQueue<Integer> queue = new MyQueue<>();

        Scanner scan = new Scanner(System.in);
        int n = scan.nextInt();

        for (int i = 0; i < n; i++) {
            int operation = scan.nextInt();
            if (operation == 1) { // enqueue
                queue.enqueue(scan.nextInt());
            } else if (operation == 2 || operation == 3) { // dequeue
                queue.dequeueOrPeek(operation);
            }
        }
        scan.close();
    }

CTCI Challange, DAY 5

Day 5:-

Program Statement:-Stacks: Balanced Brackets


On Paper:-


import java.util.ArrayList;
import java.util.Scanner;
import java.util.Stack;

/**
 * @author vikram.shanbogar@gmail.com
 * on 7/30/2017.
 */
public class Stacks {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        int n = scan.nextInt();
        String[] strs = new String[n];
        for (int i = 0; i < n; i++) {
            String expression = scan.next();
            if (expression.length() % 2 != 0) {
                strs[i] = "NO";
            } else
                strs[i] = ((isBalanced(expression)) ? "YES" : "NO");
        }
        for (int i = 0; i < strs.length; i++) {
            System.out.println(strs[i]);
        }
    }

    static boolean isBalanced(String expression) {
        Stack<Character> stack;
        boolean result = true;
        stack = new Stack<>();
        for (int i = 0; i < expression.length(); i++) {
            if ((expression.charAt(i) != '{') && (expression.charAt(i) != '(') && (expression.charAt(i) != '[') &&
                    (expression.charAt(i) != '}') && (expression.charAt(i) != ')') && (expression.charAt(i) != ']')) {
                result = false;
                break;
            }
            if (expression.charAt(i) == '{' || expression.charAt(i) == '(' || expression.charAt(i) == '[') {
                stack.push(expression.charAt(i));
            } else if (!stack.isEmpty()) {
                if (stack.peek() == '{' && expression.charAt(i) == '}' || stack.peek() == '[' && expression.charAt(i) == ']'
                        || stack.peek() == '(' && expression.charAt(i) == ')') {
                    stack.pop();
                } else {
                    result = false;
                    break;
                }
            } else {
                result = false;
                break;
            }
        }
        if (!stack.isEmpty())
            result = false;
        return result;
    }
}

Mistakes:-

  • I was over confident.
  • I didn't test enough with different scenarios.
  • EmptyStackexception, etc

Saturday, 29 July 2017

CTCI Challange, DAY 4

Day 4:-

Problem statement:- Linked Lists: Detect a Cycle

I have studied a lot on linked lists but was very lazy in implementing its functionalities as i felt its very easy while watching it in videos.But when I started working on this It was very confusing :-)

Solved it in 30 min,very happy and was able to run it in first iteration only,Double happy :-)

On Paper:


Program:-

public class LinkedList {
    /*
Detect a cycle in a linked list. Note that the head pointer may be 'null' if the list is empty.
A Node is defined as:
*/
    class Node {
        int data;
        Node next;
    }

    static Node head;

    boolean hasCycle(Node head) {
        if (head == null) {
            return false;
        }
        String result = "no cycle";
        Node temp = head;
        Map<Node, Integer> map = new HashMap<>();
        while (temp.next != null) {
            if (!map.containsKey(temp.next)) {
                map.put(temp, 1);
                temp = temp.next;
            } else {
                result = "cycle exist";
                break;
            }
        }
        System.out.println(result);
        return true;
    }

    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        int n = scan.nextInt();
        LinkedList ll = new LinkedList();
        for (int i = 0; i < n; i++) {
            ll.insert(scan.nextInt());
        }
        ll.hasCycle(head);
    }

    private void insert(int data) {
        if (head == null) {
            head = new Node();
            head.data = data;
            head.next = null;
            return;
        }
        Node temp = head;
        while (temp.next != null) {
            temp = temp.next;
        }
        Node n = new Node();
        n.data = data;
        n.next = null;
        temp.next = n;
     /*   if (data == 2){
            temp.next = head.next;
        }*/
    }
}

Thursday, 27 July 2017

CTCI Challange, DAY 3

Day 3:-
Problem Statement:- Hash Tables: Ransom Note

Todays problem is on hashtables(maps).
The problem was very easy,wrote it on paper with in 11 min,n coded in system.This time I maintained modularity and naming conventions.
Was able to derive at the correct solution in 4th iteration.
I tested with edge case scenarios as told by gayle in 7 step approach,yes it helped in identifying the issues quickly.

On Paper:-




import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;

public class Ransom_Note {

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int m = in.nextInt();
        int n = in.nextInt();
        String magazine[] = new String[m];
        for (int magazine_i = 0; magazine_i < m; magazine_i++) {
            magazine[magazine_i] = in.next();
        }
        String ransom[] = new String[n];
        for (int ransom_i = 0; ransom_i < n; ransom_i++) {
            ransom[ransom_i] = in.next();
        }
        System.out.println(isRansomNotePossible(magazine, ransom));
    }

    private static String isRansomNotePossible(String[] magazine, String[] ransom) {
        Map<String, Integer> mgz_map = new HashMap<>();
        Map<String, Integer> rnsm_map = new HashMap<>();

        for (int i = 0; i < magazine.length; i++) {
            if (mgz_map.containsKey(magazine[i])) {
                int val = mgz_map.get(magazine[i]);
                mgz_map.put(magazine[i], ++val);
            } else {
                mgz_map.put(magazine[i], 1);
            }
        }
        for (int i = 0; i < ransom.length; i++) {
            if (rnsm_map.containsKey(ransom[i])) {
                int val = rnsm_map.get(ransom[i]);
                rnsm_map.put(ransom[i], ++val);
            } else {
                rnsm_map.put(ransom[i], 1);
            }
        }

        String result = "Yes";
        for (String key : rnsm_map.keySet()
                ) {
            if (!mgz_map.containsKey(key)) {
                result = "No";
                break;
            } else if (mgz_map.containsKey(key) && rnsm_map.get(key) > mgz_map.get(key)) {
                result = "No";
                break;
            }
        }
        return result;
    }
}

Mistakes:-
I tried to iterate over mgz.map contents but there's a possibility that rnsm_map can contain values other than mgz_map values.So I interchanged it.

Wednesday, 26 July 2017

CTCI Challange, DAY 2

Problem Statement:- Strings: Making Anagrams

One good thing was i solved these strings related problems before in hackerrank, so I was confident before starting itself.

Start point:-
Problem was easy,I knew Just using the maps and the for loop it can be solved.

On Paper:-


import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class Making_Anagrams {

    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        String a = scan.nextLine();
        String b = scan.nextLine();
        Map<Character, Integer> aMap = new HashMap<>();
        Map<Character, Integer> bMap = new HashMap<>();
        for (int i = 0; i < a.length(); i++) {
            if (aMap.containsKey(a.charAt(i))) {
                int count = aMap.get(a.charAt(i));
                count++;
                aMap.put(a.charAt(i), count);
            } else {
                aMap.put(a.charAt(i), 1);
            }
        }
        for (int i = 0; i < b.length(); i++) {
            if (bMap.containsKey(b.charAt(i))) {
                int count = bMap.get(b.charAt(i));
                count++;
                bMap.put(b.charAt(i), count);
            } else {
                bMap.put(b.charAt(i), 1);
            }
        }
        String temp = a;
        int charsToDelete = 0;
        for (int i = 0; i < temp.length(); i++) {
            if (aMap.containsKey(temp.charAt(i)) && bMap.containsKey(temp.charAt(i))) {
                if (aMap.get(temp.charAt(i)) != bMap.get(temp.charAt(i))) {
                    charsToDelete += Math.abs((aMap.get(temp.charAt(i)) - bMap.get(temp.charAt(i))));
                    aMap.put(temp.charAt(i), 0); //if this is not setted here then it will be recalculated for the next string also.
                    bMap.put(temp.charAt(i), 0);
                }
            } else {
                charsToDelete += aMap.containsKey(temp.charAt(i)) ? aMap.get(temp.charAt(i)) : bMap.get(temp.charAt(i));
                aMap.put(temp.charAt(i), 0);
                bMap.put(temp.charAt(i), 0);
            }
        }
        temp = b;
        for (int i = 0; i < temp.length(); i++) {
            if (aMap.containsKey(temp.charAt(i)) && bMap.containsKey(temp.charAt(i))) {
                if (aMap.get(temp.charAt(i)) != bMap.get(temp.charAt(i))) {
                    charsToDelete += Math.abs((aMap.get(temp.charAt(i)) - bMap.get(temp.charAt(i))));
                    aMap.put(temp.charAt(i), 0);
                    bMap.put(temp.charAt(i), 0);
                }
            } else {
                charsToDelete += aMap.containsKey(temp.charAt(i)) ? aMap.get(temp.charAt(i)) :                bMap.get(temp.charAt(i));
                aMap.put(temp.charAt(i), 0);
                bMap.put(temp.charAt(i), 0);
            }
        }
        System.out.println(charsToDelete);
    }
}

Mistakes:-
1. I failed to maintain the modularity,I was in a hurry(take care next time!)
2. Naming of variables should be still more elaborate.
3. The code on paper should be complete,just a psudocode is not enough.

Tuesday, 25 July 2017

CTCI Challange, DAY 1

Gayle laakmann mcdowell has provided few guidence videos on how to solve the algorithms and about the Algorithm Strategies.

7 Steps to Solve Algorithm Problems

3 Algorithm Strategies

Problem Statement:- Arrays: Left Rotation

I solved my first day problem on Arrays.

Easy but took 1.5 hours to complete with 10 iterations.2 test cases failed due to time error.Good need to catch up a lot tmrw.

public class Arrays_Left_Rotation {
//TODO remove the temp array
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        int n = scan.nextInt();
        int d = scan.nextInt();
        int[] array = new int[n];
        for (int i = 0; i < n; i++) {
            array[i] = scan.nextInt();
        }
        int k = d % n;
        int temp[] = new int[n];
        for (int i = 0; i < n; i++) {
            int count = 0, j = i;
            while (count != k) {
                if (j == 0)
                    j = n - 1;
                else
                    j--;
                count++;
            }
            temp[j] = array[i];
        }
        for (int i = 0; i < n; i++) {
            System.out.print(temp[i] + " ");
        }
    }


20 Day Cracking the Coding Interview(CTCI) Challenge

Inspired by max(https://medium.com/@maxdeutsch/m2m-day-1-completing-12-ridiculously-hard-challenges-in-12-months-9843700c741f), i am starting the tiny challenge of 20 day daily blogging of my quest of completing CTCI in 20 days in HackerRank.

The actual book Cracking the Coding Interview(CTCI) has 150+ problems but the books author and Hackerrank have come together and provided a 20 problems set which covers the important chapters of the book.

Whats the Challenge?

  • Go through the problem statement.
  • 30 min to understand,analyze and formulate the problem on paper.
  • At max 5 iterations to solve it in IDE,Gradually reduce the iterations by the end of 20 days.
  • 1 Problem everyday,no matter the circumstance you are in.
  • Blog the steps taken for the day.

Why is this Challenge?

I want to be disciplined, I have postponed solving CTCI for almost a year now.

Monday, 3 July 2017

Notes on Algorithms, Part I by Princeton University

After postponing for 3-6 months finally I took Algorithms 1 course in June-july 2017.

Notes:-

Week 1:-
Problem Statement:- percolation.pdf
I have spent nearly 10-15 hours on solving the percolation problem.Its totally worth it.

Mistakes:-
  • I tried to solve the problem without understanding completely.
  • I wasted lot of time in checking for references and help online.
This video helped me a lot in understanding the problem:- https://www.youtube.com/watch?v=BiSKunzrC1g

Github link:- week1

Note:- Please use the below code for reference only,else it will spoil the fun:-)
Percolation problem:-     github link

PercolationStats :-            github link

Analysis of algos:-



Week 2:-
Stacks And Queues:-
  • Implement each using either a singly-linked list or a resizing array.
  • Importance of generics and iterators.
  • parsing arithmetic expressions using Dijkstra Algorithm

Sorting:-
Basic Sorting Algorithms with O(n2) time complexity.






Shuffle:-
Knuth Algorithm:-
   public static void shuffle(Object[] a) {

int n = a.length;
        for (int i = 0; i < n; i++) {
            // choose index uniformly in [0, i]
            int r = (int) (Math.random() * (i + 1));
            Object swap = a[r];
            a[r] = a[i];
            a[i] = swap;
        }
    }
Week 3:-
MergeSort:
very good stable algorithm for sorting.

Performance = O(nlogn)
Space = O(n)  !!!Major drawback it requires n spaces
It uses recursion:-
mergesort(array){
 mergesort(leftarray)
 mergesort(rightarray)
 merge left half n right half in sorted order
 }
public class MergeSort {
 public static void mergesort(Comparable[] array) {
  Comparable[] temp = new Comparable[array.length];
  mergesort(array, temp, 0, array.length - 1);
  show(temp);
 }
public static void mergesort(Comparable[] array, Comparable[] temp, int leftStart,
 int rightEnd) {
if (leftStart >= rightEnd) {
   return;
  }
  int middle = (leftStart + rightEnd) / 2;
  mergesort(array, temp, leftStart, middle);
  mergesort(array, temp, middle + 1, rightEnd);
  merge(array, temp, leftStart, rightEnd);
 }
@SuppressWarnings("unchecked")
 public static void merge(Comparable[] array,Comparable[] temp,int leftStart,int rightEnd) {
  int leftEnd = (leftStart + rightEnd) / 2;
  int rightStart = leftEnd + 1;
  int size = rightEnd - leftStart + 1;
  int index = leftStart;//index to temp array,need to start from beginning i.e leftStart
  while (leftStart <= leftEnd && rightStart <= rightEnd) {
   if (array[leftStart].compareTo(array[rightStart]) < 0) {
    temp[index] = array[leftStart];
    leftStart++;
   } else {
    temp[index] = array[rightStart];
    rightStart++;
   }
   index++;
  }
  for (int i = leftStart; i <= leftEnd; i++) {
   temp[index] = array[i];
   index++;
  }
  for (int i = rightStart; i <= rightEnd; i++) {
   temp[index] = array[i];
   index++;
  }
  for (int i = leftStart; i <= rightEnd; i++) {
   array[i] = temp[i];
  }
  // System.arraycopy(array, leftStart, temp, index, leftEnd - leftStart + 1);
  // System.arraycopy(array, rightStart, temp, index, rightEnd - rightStart + 1);
  // System.arraycopy(temp, leftStart, array, leftStart, size);
 }
private static void show(Comparable[] temp) {
  for (int i = 0; i < temp.length; i++) {
   System.out.print("\t" + temp[i]);
  }
}

QuickSort:-(Lomuto partition scheme)

// Java program for implementation of QuickSort
class QuickSort
{
    /* This function takes last element as pivot,
       places the pivot element at its correct
       position in sorted array, and places all
       smaller (smaller than pivot) to left of
       pivot and all greater elements to right
       of pivot */
    int partition(int arr[], int low, int high)
    {
        int pivot = arr[high]; 
        int i = (low-1); // index of smaller element
        for (int j=low; j<high; j++)
        {
            // If current element is smaller than or
            // equal to pivot
            if (arr[j] <= pivot)
            {
                i++;

                // swap arr[i] and arr[j]
                int temp = arr[i];
                arr[i] = arr[j];
                arr[j] = temp;
            }
        }

        // swap arr[i+1] and arr[high] (or pivot)
        int temp = arr[i+1];
        arr[i+1] = arr[high];
        arr[high] = temp;

        return i+1;
    }


    /* The main function that implements QuickSort()
      arr[] --> Array to be sorted,
      low  --> Starting index,
      high  --> Ending index */
    void sort(int arr[], int low, int high)
    {
        if (low < high)
        {
            /* pi is partitioning index, arr[pi] is 
              now at right place */
            int pi = partition(arr, low, high);

            // Recursively sort elements before
            // partition and after partition
            sort(arr, low, pi-1);
            sort(arr, pi+1, high);
        }
    }

    /* A utility function to print array of size n */
    static void printArray(int arr[])
    {
        int n = arr.length;
        for (int i=0; i<n; ++i)
            System.out.print(arr[i]+" ");
        System.out.println();
    }

    // Driver program
    public static void main(String args[])
    {
        int arr[] = {10, 7, 8, 9, 1, 5};
        int n = arr.length;

        QuickSort ob = new QuickSort();
        ob.sort(arr, 0, n-1);

        System.out.println("sorted array");
        printArray(arr);
    }
}


Hoare’s Partition Scheme
Hoare’s Partition Scheme works by initializing two indexes that start at two ends, the two indexes move toward each other until an inversion is (A smaller value on left side and greater value on right side) found. When an inversion is found, two values are swapped and process is repeated.



artition(arr[], lo, hi)
   pivot = arr[lo]
   i = lo - 1  // Initialize left index
   j = hi + 1  // Initialize right index

   // Find a value in left side greater
   // than pivot
   do
      i = i + 1
   while arr[i] < pivot

   // Find a value in right side smaller
   // than pivot
   do
      j = j - 1
   while arr[i] > pivot

   if i >= j then 
      return j

   swap arr[i] with arr[j]


WEEK 4:-
PriorityQueues:-
– binary tree: empty or node with links to left and right binary trees
– complete B tree: perfectly balanced, except for bottom level
– complete B tree height h: lg N (h increases when N is a power of 2)
Binary heap:-
The items are stored in an array such that each key is guaranteed to be larger than (or equal to) the keys at two other specific positions.
parent's key >= children's keys
The parent of the node in position k is in position k/2; and, conversely, the two children of the node in position k are in positions 2k and 2k + 1
To move up the tree from a[k] we set k to k/2; to move down the tree we set k to 2*k or 2*k+1
– Largest key is a[1], root of b.tree
if child becomes larger than parent then:
– swap child, parent; repeat up until in order
private void swim(int k) {
   while (k > 1 && less(k/2, k)) {
      exch(k, k/2);
      k = k/2;
   }
}
Insert: add to end, swim up: at most 1+lg N compares
pq[++N] = x, swim(N)
– parent becomes smaller than child
private void sink(int k)
    while (2*k <= N) {
        int j = 2*k;
        if (j < N && less(j, j+1)) j++;
        if (!less(k, j)) break;
        exch(k, j);
        k = j;
        }
delMax: swap root, tail; sink root down
max = pq[1], swap(1, N--), sink(1);


Binary Search Trees:-
– A BST is a binary tree in symmetric order
symmetric order:- The node is larger than its left element and smaller than its right element.
– each node (key, value, left right): empty or BST (each node is a root of a subtree)
– symmetric order: every node key is: larger than in left, smaller than in right
BST search
private Value get(Node x, Key key)
    if (x == null) return null;
    int cmp = key.compareTo(x.key);
    if      (cmp < 0) return get(x.left, key);
    else if (cmp > 0) return get(x.right, key);
    else              return x.val;
BST insert: search for key, 2 cases: key in tree: reset value or: add new node
private Node put(Node x, Key key, Value val)
    if (x == null) return new Node(key, val, 1);
    int cmp = key.compareTo(x.key);
    if      (cmp < 0) x.left  = put(x.left,  key, val);
    else if (cmp > 0) x.right = put(x.right, key, val);
    else              x.val   = val;
    x.N = 1 + size(x.left) + size(x.right); // update tree size
    return x;

Week 5:-



As you can see from above table,we need do balance the tree somehow to reach the goal of logN for all operations.




Week 6:-
The performance of the map can be increased if we use array instead of othr data structures.we need a function which can convert the key into index and also reduce the collision.This function is called Hash function.

But the collision occurs when the Hash function returns same hash value(index) for different keys.




Avoid Collision:
1. Seperate Chaining(build, for each of the M array indices, a linked list of the key-value pairs whose keys hash to that index)
2. Open Addressing.
a. linear probing
hi(X) = (Hash(X)+i) % size
if h0 = (Hash(X)+0) % size if full will try for h1
if h1 = (Hash(X)+1) % size if full will try for h2

b. quadratic probing

c. Double probing

Tries

Tries stands for reTRIEval.

Used in string prefix finding etc

Takeaways:

The key takeaways for me after completing the algorithms part 1 course is that:-


  • I got to know, how to build the algorithms and progressively improve it.
  • I got to know about many algorithms of sorting and trees.
  • I gained lot of confidence after working on percolation problem,At one stage I gave up learning the algorithms course as I was unable to understand the code at all.But now I am able to understand and solve the problems.
  • I spent lot of time in understanding the Asymptotic notions but only after taking this course I am able to apply those concepts and analyze in real time.
  • Some of the java concepts like generics,Iterators,Comparators were very useful
  • After solving some of the geometric problems,I am awe struck by the wide spectrum that algorithms cover.

Installing Docker and Minikube

  install docker-   sudo apt install docker.io   set user to docker group:- sudo gpasswd -a   {user} docker   imp commands:- ...