Showing posts with label Interview. Show all posts
Showing posts with label Interview. Show all posts

Friday, December 25, 2015

Amazon Interview 1: Problem 2

Problem 2: Given two linked lists. Each node stores a single digit. Each linked list this way represents a decimal number, with number of digits = number of nodes in the list. You need to add them to produce a third list which represents the sum of the numbers.

Problem statement would be complete only if we know the how decimal numbers are represented in the list.


To represent .123 the list is 1 -> 2-> 3


To add 2 numbers, you must consider the following scenario:


List 1 = 4 -> 5 -> 6

List 2 = 6 -> 9

Returned list should be 1 -> 1 -> 4 -> 6 (Though if this is considered only decimal number, it would be incorrect) but for time being let's consider this as a solution.


Solution 1: Modify the shorter list to append the '0' (Zero) to make both the lists size equal. For each list reach to ith location (1 <= i <= N ) starting from the Size of the list and add both the lists. If sum is greater than one use carry to add (i - 1) position.


List 1 => 4 -> 5 -> 6

List 2 => 6 -> 9 -> 0

When I = 3 (Iteration to reach 3rd position = 3)

List 3 => 6
Carry = 0

When I = 2 (Iteration to reach 3rd position = 2)

List 3 => 4 -> 6
Carry  = 1

When I = 1 (Iteration to reach 3rd position = 1)

List 3 => 1 -> 4 -> 6
Carry = 1

Exit the loop and add carry to list 3

List 3 => 1 -> 1 -> 4 -> 6

Time Complexity: 3 + 2 + 1 (N = 3)

Time Complexity for N elements: N + (N-1) + .... + 1 = N(N+1)/2 = O(N*N)

Time complexity of the above solution is O(N*N)


Solution 2: You can even reverse the lists and add them simply. But reversing the list would also require O(N*N) time complexity, and you would change the original structure of the input which is not desirable.


Solution 3: Here is another idea which performs better in normal circumstances, whereas in worst case it has same O(N*N) time complexity.




Logic
 method add start
  input list1 and list2
  minLength = find the smaller length of both the list
  assign a boolean array of len = minLength
  create a node with sum of list1 and list 2 digit mod 10
  array[0] = assign true if sum is greater than zero
  repeatTill = array[0] == true? 0:-1;
  for element from 1 to min length
   create a node with sum of list1 and list 2 digit mod 10
   array[element] = assign true if sum is greater than zero  
   repeatTill = array[element] == true? element:repeatTill;
  end for
  assign the remaining elements of the longer list to new list
  call recursive method to update the carries
 end
 
 method updateCarries start
  input list3, boolean[] array, repeatTill
  if repeatTill is negative then
   return list3
  end if
  if array[0] is true then
   add Node with digit 1 at front of the list
  end if
  for element from 1 to repeatTill
   if array[element] is true then
    assign repeatTill if array[element-1] is true
    update values
   end if
  end for
  return call updateCarries
 end



This solution's best case is O(N) when there is no carry in these two digits. For Example when 123 and 234 are added. In this case, loop is iterated only once.

Whereas in the worst case it will run for O(N*N). That would be most unusual addition. For Example when 9999 and 0001 are added. In this case, N*(N+1)/2 elements are accessed.

Java code for the solution is as following:

Java Code
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * Problem: Given two linked lists. Each node stores a single digit. Each linked
 * list this way represents a decimal number, with number of digits = number of
 * nodes in the list. You need to add then to produce a third list which
 * represents the sum of the numbers.
 * 
 * E.G. LinkedList 1 -> 2 -> 6 LinkedList 3 -> 8
 * 
 *
 */
public class SumDecimal {

 /**
  * This method reads the input and prepares the array and call the relevant
  * method.
  * 
  * @param args
  * @throws IOException
  */
 public static void main(String[] args) throws IOException {

  BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
  String line = br.readLine();
  /**
   * N is the number of test cases.
   */
  int N = Integer.parseInt(line);
  for (int i = 0; i < N; i++) {
   String[] list1Values = br.readLine().split(" ");
   String[] list2Values = br.readLine().split(" ");
   Node list1 = null;
   for (int index = list1Values.length - 1; index >= 0; index--) {
    Node n = new Node(Integer.parseInt(list1Values[index]));
    n.next = list1;
    list1 = n;
   }
   Node list2 = null;
   for (int index = list2Values.length - 1; index >= 0; index--) {
    Node n = new Node(Integer.parseInt(list2Values[index]));
    n.next = list2;
    list2 = n;
   }
   Node list3 = add(list1, list2);
   System.out.println(list3);
  }
 }

 private static Node add(Node list1, Node list2) {
  int minLength = 1;
  Node l1 = list1;
  Node l2 = list2;
  while (l1.next != null && l2.next != null) {
   minLength++; // M or N whatever is smaller.
   l1 = l1.next;
   l2 = l2.next;
  }
  boolean[] carries = new boolean[minLength];
  Node list3 = new Node((list1.digit + list2.digit) % 10);
  Node list = list3;
  carries[0] = (list1.digit + list2.digit) / 10 == 0 ? false : true;
  int toMove = carries[0] ? 0 : -1;
  for (int index = 1; index < minLength; index++) {
   Node n = new Node((list1.next.digit + list2.next.digit) % 10);
   carries[index] = (list1.next.digit + list2.next.digit) / 10 == 0 ? false : true;
   list1 = list1.next;
   list2 = list2.next;
   list3.next = n;
   list3 = list3.next;
   toMove = carries[index] ? index : toMove;
  }
  if (list1.next != null) {
   list3.next = list1.next;
  } else {
   list3.next = list2.next;
  }
  list = updateCarries(list, carries, toMove);
  return list;
 }

 private static Node updateCarries(Node list3, boolean[] carries, int toMove) {
  if (toMove == -1)
   return list3;
  int nextMove = -1;
  Node list = list3;
  if (carries[0]) {
   Node n = new Node(1);
   n.next = list3;
   list = n;
   carries[0] = false;
  }
  for (int index = 1; index <= toMove; index++) {
   if (carries[index]) {
    int sum = list3.digit + 1;
    carries[index - 1] = sum == 10 ? true : false;
    list3.digit = sum % 10;
    carries[index] = false;
    nextMove = carries[index - 1] ? index - 1 : nextMove;
   }
   list3 = list3.next;
  }
  return updateCarries(list, carries, nextMove);
 }

 static class Node {
  int digit;
  Node next;

  Node(int digit) {
   this.digit = digit;
  }

  public String toString() {
   return (next == null) ? digit + "" : digit + " " + next.toString();
  }
 }

}



Input
7
1 2 3
2 3 4
3 4 5
3 4 5
9 9 9
0 0 1
9 0 0
1 9 9
9 8 1
1 2
1 2 6 8 9 6 7 8 9
9
1 2 6 8 9 6 7 8 9
9 8 4 2 1 4 3 8 7

Output
3 5 7
6 9 0
9 9 9
1 0 9 9
1 1 0 1
1 0 2 6 8 9 6 7 8 9
1 1 1 1 1 1 1 1 7 6

If you feel that something is not correct with the solution, let me know. I would try to fix the problem.

Wednesday, December 23, 2015

Design Patterns: Coffee Vending Machine

The question was asked in an interview to design a coffee vending machine.

Most importantly it is required for us to create the object with the help of creational design patterns. We would try to go through all the creational patterns which are widely known to us.

Let's start with Builder design pattern.
Builder design pattern is applied when the object constructed is huge and application would want to split the responsibility of object creation to various different objects. It can even give you the flexibility to sneak in the different implementations of a certain object based on need.

Does this DP fit to design the coffee vending machine?
Let's look over at the requirement. Coffee vending machine dispatches only few basic things i.e. various tea, various coffees, and hot water. None of the objects are really complex in nature. So it would be waste to invest so much efforts to apply builder pattern for the given problem.

Okay, let's take up another pattern i.e. Singleton design pattern.
Singleton design patterns knowing or unknowing have been in use for us. The idea behind this pattern to allow only one instance across the application. One instance must serve the need of all object requirement.

Instead analyzing this overly, we can conclude that single instance can not serve our purpose in this case. So we can not apply singleton design pattern for our application.

Moving on to Factory Abstract design pattern. (during the interview, I was using this design pattern to implement coffee vending machine)
Factory abstract design application build various different objects based on the requirement. Application would not really not know the product yet, the object created would serve the purpose of the operation. In this case application would require one class/product for each type of product type.

Does this DP fit to design the coffee vending machine?
If vending machine is used to get hot water, an object of hot water class must be returned. In this where the options could be unlimited Factory Abstract limits these options. To add another option, application would always need to introduce new class and add the application's main object which returns the output.

Could Factory Method design pattern suffice the need for this?
Based on my understanding abstract factory and factory method are almost the same. The difference lies between the responsibility of object creation. In case of factory method, object creation responsibility is designated to a factory method.

So applying this method would also be difficult in our scenario.

Let's look at the last known creational DP i.e. Prototype DP. In this design pattern we maintain a registry of object at some place and clone the object as per the need. It is very similar to on demand object creation. So in this DP also we would need to create as many classes as the options in the vending machine. Again, we would be writing way too much code for our work.

As we could not achieve the best design pattern mechanism with the help of creational design pattern. Let's move to other side of design patterns.

Let's look at the requirement in a different way.

Coffee Vending machine is using Coffee, Tea, Water, Milk, and Sugar to create all the available options. It might be needed that option might be needed to add lemon in the water and sugar to create lemon tea. In this case, we can use mix of two patterns. One abstract factory pattern and another is decorator patterns to decorate the object based on need.

Utilization of Abstract Factory pattern. Create 3 separate classes for Water, Coffee, and Tea. These 3 are the main component of the vending machine.

Now decorate the Coffee object with milk to make it milk coffee. Coffee object in itself can be utilized for espresso. Whereas in case tea, we can add various style based on the need.

milkCoffee = new Coffee(new Milk());
milkTea = new Tea(new Milk(new Masala()))
gingerTea = new Tea(new Milk(new Ginger()))
gingerMasalaTea = new Tea(new Milk(new Ginger(new Masala())))

Styling the tea and coffee can be solved with decorator pattern.

Why did we use different objects for tea and coffee?
Tea, Coffee, and Water are different products. So based on usual product understanding, we kept them separate and added styles later which are ginger to tea, masala to tea, and so on. Though it is possible to add the styles to the water to create coffee and tea also.
milkCoffee = new Water(Coffee(new Milk()));

If you think that your understanding deviates from mine. Let me know. We can discuss that in details.

Wednesday, December 9, 2015

Oracle Interview - Telephonic Round - Continues

We did not solve the last problem that I was asked in the interview. So let's put together the solution for the same.
  • Algorithm Problem: A random string is provided to you, you must find the minimum number of elements to be inserted in the string to make it palindrome.
    • String is ABA, then method must return 0.
    • String is ABC, then method must return 2 to form ABCBA.
    • String ABCDA, then method must return 2 to form ABCDCBA.
    • String ASD3D5, then method must return 3 to form AS5D3D5SA.
It has been difficult for me to find the solutions for the problem within the specified timeframe as it requires quite a good understanding to achieve such an efficient answers.

When I first heard the question, I felt that this would round would not be difficult as I thought, as I could come up with the algorithm within some time. But I was wrong. It was not the case there.

First Solution
 public class Palindrome {  
      String element;  
      public Palindrome(final String elem) {  
           element = elem;  
      }  
      public int makePalindrome() {  
           if (element.length() <= 1) {  
                return 0;  
           } else {  
                char[] dst = new char[element.length()];  
                int endIndex = element.length() - 1;  
                int index = 0;  
                element.getChars(0, element.length(), dst, 0);  
                while (dst[index] == dst[endIndex]) {  
                     index++;  
                     endIndex--;  
                }  
                return endIndex - index;  
           }  
      }  
      /**  
       * @param args  
       */  
      public static void main(String[] args) {  
           Palindrome p = new Palindrome("ABCA");  
           System.out.println("Chars to be added are: " + p.makePalindrome());  
      }  
 }  

Oh wow, that's it. But it is really worth the question.

What I did?
I solved for ABA, and it would return 0 but it was not the smallest palindrome. After discussion with interview a bit more, I can to know that this code would really not work for "ASD3D5". It was true, the code did not really work as per the question. Hell broke lose here. Now interviewer is already agitated with the time that I have taken.

I have to rework the solution with the closed mind. Stupid mind was still contemplating me to write some code on the same line, and it was not able to think something different at that time. However I failed the interview at that time only, but it was required for me to find the answer for the questions that are asked.

I tried little more and found the following answer.

Solution 2
It is simple, we have to use the dynamic programming to solve the issue that we have in hand. First we cut the corners of the string. In case of ABCDA, we use string BCD for the dynamic programming. Now we find the maximum number of elements which matches between original string and reversed string. Count of minimum non matching characters are the solution for the puzzle.

1:  package com.oracle;  
2:  import java.util.Collections;  
3:  import java.util.List;  
4:  public class Palindrome {  
5:       String element;  
6:       public Palindrome(final String elem) {  
7:            element = elem;  
8:       }  
9:       public int makePalindrome() {  
10:            if (element.length() <= 1) {  
11:                 return 0;  
12:            } else {  
13:                 char[] dst = new char[element.length()];  
14:                 int endIndex = element.length() - 1;  
15:                 int index = 0;  
16:                 element.getChars(0, element.length(), dst, 0);  
17:                 while (dst[index] == dst[endIndex]) {  
18:                      index++;  
19:                      endIndex--;  
20:                 }  
21:                 String substring = element.substring(index, endIndex + 1);  
22:                 System.out.println("New String is: " + substring);  
23:                 return Math.min(substring.length(),  
24:                           minCharForPalindrome(substring.toCharArray(), 0));  
25:            }  
26:       }  
27:       private int minCharForPalindrome(char[] substringArray, int compare) {  
28:            if(compare > substringArray.length){  
29:                 return compare;  
30:            }  
31:            int count = 0;  
32:            for (int index = compare, last = substringArray.length - 1; 
                   index < substringArray.length; index++, last--) {  
33:                 if (substringArray[index] != substringArray[last]) {  
34:                      count++;  
35:                 }  
36:            }  
37:            count += compare;  
38:            System.out.println("When Compare = " + compare + " Count= " + count);  
39:            return Math.min(count,  minCharForPalindrome(substringArray, ++compare));  
40:       }  
41:       /**  
42:        * @param args  
43:        */  
44:       public static void main(String[] args) {  
45:            Palindrome p = new Palindrome("ABCDEFG");  
46:            System.out.println("Chars to be added are: " + p.makePalindrome());  
47:       }  
48:  }  

This solution is based on the dynamic programming where starting from the first point string is compared with the another string. The solution is general should take O(N*N) time to compute the result.
1:  New String is: ABCDEFG  
2:  When Compare = 0 Count= 6  
3:  When Compare = 1 Count= 7  
4:  When Compare = 2 Count= 6  
5:  When Compare = 3 Count= 7  
6:  When Compare = 4 Count= 6  
7:  When Compare = 5 Count= 7  
8:  When Compare = 6 Count= 6  
9:  When Compare = 7 Count= 7  
10:  Chars to be added are: 6  

1:  New String is: ASD3D5  
2:  When Compare = 0 Count= 6  
3:  When Compare = 1 Count= 3  
4:  When Compare = 2 Count= 6  
5:  When Compare = 3 Count= 5  
6:  When Compare = 4 Count= 6  
7:  When Compare = 5 Count= 5  
8:  When Compare = 6 Count= 6  
9:  Chars to be added are: 3  

Now the problem with the solution is the time complexity. Can we do anything better?

Okay few people says yes. There is one solution which uses Knuth-Morris-Pratt Algo to find the solutions more efficiently.I have not implemented it yet, but I would surely try to implement and understand it. If you have understood the same, please suggest me the same.

Links for the reference are as following:
https://en.wikipedia.org/wiki/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm
http://stackoverflow.com/questions/18732020/add-the-least-amount-of-characters-to-make-a-palindrome

Hope it helps

Tuesday, December 8, 2015

Oracle Interview - Telephonic Round

It was a telephonic discussion session for the post of senior software developer. Though I could not clear the round yet it would be best place to share the questions so that I can discuss whether there can be other solutions for the problems asked.

  • What are the differences between JDK, JRE, and JVM?
JDK (Java Development Kit): Development Kit which is actually required for the developers. It is not required to run the Java dependent applications. It is rather required at the development.
JRE (Java Runtime Environment): Java Runtime environment is required to run the java application. It computer does not JRE, No Java application can run on it.
JVM (Java Virtual Machine): JVM is part of JRE, it reads byte code and execute them on the Hardware. It is the reason which causes JAVA applications to run on various platforms without changing much at the program level.
  • Design Problem: You have to build a data/class model for a website. It has users i.e. People and it has group. A User can belong to multiple groups and a Group can have multiple users. Each group maintains an individual account. All the transactions are saved with the person who made the expenses and each person's share is calculated on each transaction. Person vice credit/debit history should also be maintained. Build the data structure for the same.
Design problems are some problem when interviewer and interviewee both do not have same understanding of the requirement. Such problems must only be discussed when you are speaking face to face. It not only gives more confidence but also provides more error correction while writing the code.

For this specific design problem, I had assumed that group is the prime information that system has, whereas Interviewer was expecting that Person should be the prima facie of the complete system. Though it was not difficult both the ways, but it is planned in separate way for both entities.

First Design
Application would have four classes as following

1:   public class Group{  
2:   List<Person> members;  
3:   List<Transaction> transactions;  
4:   List<Share> shares;  
5:   double totalExpenditure;  
6:   //Methods  
7:   addPerson  
8:   addTransaction  
9:   settleAmount  
10:   getShare for a person  
11:   }  
12:   public class Person{  
13:   String name;  
14:   List<Group> groups;  
15:   double credit;  
16:   double debit;  
17:   //Method  
18:   addToCredit  
19:   addToDebit  
20:   addGroup  
21:   }  
22:   public class Share{  
23:   double credit;  
24:   double debit;  
25:   Person belongsTo;  
26:   //Changes with each transaction.  
27:   }  
28:   //Transaction once added, it would be required it to modify.  
29:   public final class Transaction{ //Immutable class  
30:   final String type;  
31:   final String expenseReason;  
32:   final double amount;  
33:   final Person spentBy;  
34:   public Transaction(final String t, final String r, final double amount, final Person p){  
35:    type = t;  
36:    expenseReason = r;  
37:    this.amount = amount;  
38:    spentBy = p;  
39:   }  
40:   }  
Now when the system is designed from group point of view, it is considered that group is self managed and everyone part of the group would really be part of all the transactions relevant to group.

All the classes are self explanatory. Why did I make Transaction as immutable? Transaction is once done, it can not be altered later. Though there can be people who would say that 'What if user inputs the wrong data?' Oh yes, user has rights to enter wrong data, but it would be atmost 1% times.

It is best to solve the problems which are essential rather increase the complexity of the system by solving trivial problems.

However interviewer wanted to run things with the user perspective. As per him, A group is an entity based on users. User may or may not be the part of group's particular transactions. So it was required to rewrite the classes again based on the following assumption.

  //Transaction once added, it would not be required to modify it.  
  public final class Transaction{  
  final String type;  
  final String expenseReason;  
  final double amount;  
  final Person spentBy;  
  final List<Person> sharedAmong;  
  public Transaction(final String t, final String r, final double amount, final Person p, final List<Person> shared){  
   type = t;  
   expenseReason = r;  
   this.amount = amount;  
   spentBy = p;  
   sharedAmong = Collections.unmodifiableList(shared);  
  }  
  }  

However when things are user's point, then it is required to provide administrative work to someone who can create group, assign group, and perform group related works. It is required to add few fields and methods in other classes as well.

  public class Group{  
  List<Person> admins;  
         .....  
  }  
  public class Person{  
         ....  
  createGroup  
  addAdminToTheGroup  
  invitePeople  
  }  

However we can add more to it, but till this point we discussed.
  • Algorithm Problem: A random string is provided to you, you must find the minimum number of elements to be inserted in the string to make it palindrome.
    • String is ABA, then method must return 0.
    • String is ABC, then method must return 2 to form ABCBA.
    • String ABCDA, then method must return 2 to form ABCDCBA.
    • String ASD3D5, then method must return 3 to form AS5D3D5SA.
It would be best to save to Algorithm Problem for the next blog. I could not solve the problem at the time of interview, but I have a solution with O(n*n) complexity. If there is solution available which is better than this, please suggest me.

If you think that above design problem can be designed better, please suggest.

Sunday, January 19, 2014

Flipkart Interview 1: Data Structure and Algorithm

It was a telephonic discussion with Flipkart, as per its reputation, its interview throws questions to provide algorithms for them. In the first telecon, I was asked 2 questions (though the interviewer wanted to discuss 3), and those are following 2 questions.

A Binary tree is there, root of the binary tree is provided. It is asked to search a node and find all the nodes that are at a K distance from the tree.
Binary Tree - Not BST
 Consider the tree provided in the figure above.

Root of the tree is A, and it is required to find all the elements at distance 3 from Node D.
Answer should be C, J and K.

Root of the tree is A, and it is required to find all the elements at distance 2 from Node D.
Answer should be A, E, P, Q, R, and S.

Root of the tree is A, and it is required to find all the elements at distance 4 from Node D.
Answer should be T, U, V, F and G.

Solution
It is possible to create the graph where starting node of the graph is D as the starting node of the graph. Search Node along with its path. Create a graph with the help of path that was retained while searching the node, find all the nodes at distance K using BFS.

Algorithm for this as follows:
List 1
Find the element using recursion and store all the elements in a stack.
(Time complexity O(n))
Create the graph such that all the parents, catered in the stacks,
points in the other direction. i.e. D -> B-> A
(Time complexity O log(n) + Space Complexity o(Log n))
Now run the Breadth First Search algorithm to for iterations.
(Time complexity O(n))

Total time complexity for the solution is O(n + log n) = O(k*n) = O(n)
Space Complexity is O(log n). 

Let’s look at the alternative approach, as we have to change the linking, so it might not be feasible to change the DS.
List 2
Find the element using recursion and store all the elements in a stack, 
along with the side of the side of the traversal (Left or Right). 
(Time complexity O(n))
Find all downward elements that are at distance K from the node specified.
For each element pop the stack and maintain a count
From the node popped, find all the elements at (K – count) distance 
at the other side of tree.
End for each 

Let’s write a program for the method mentioned above.
We will need 2 classes for complete DS and solution.
Tree.java
class Tree {  
  char data;
  Tree left;
  Tree right;
  public Tree(char data) {
   this.data = data;
  }
  public char getData() {
   return data;
  }
  public void setData(char data) {
   this.data = data;
  }
  public Tree getLeft() {
   return left;
  }
  public void setLeft(Tree left) {
   this.left = left;
  }
  public Tree getRight() {
   return right;
  }
  public void setRight(Tree right) {
   this.right = right;
  }  
  public String toString(){
   return "" + data;
  }
 }

PathElement.java 
class PathElement {
  int direction;
  Tree node;
  public PathElement(Tree node, int dir) {
   this.node = node;
   direction = dir;
  }
  public int getDirection() {
   return direction;
  }
  public void setDirection(int direction) {
   this.direction = direction;
  }
  public Tree getNode() {
   return node;
  }
  public void setNode(Tree node) {
   this.node = node;
  }
  public String toString(){
   return ("Node:" + node.toString() + " Direction: " + direction  + "\n");
  }
 }
Search the path for element requested, and Keep the PathElement object with the stack.
List 3
 Stack path = new Stack();
 private boolean searchElement(Tree root, char search, int direction) {
  if( root == null ) return false;
  if( root.data == search ){
   path.push(new PathElement(root, direction));
   return true;
  }else{
   path.push(new PathElement(root, direction));
   boolean isInLeftTree = searchElement(root.getLeft(), search, 1);
   boolean isInRightTree = !isInLeftTree? searchElement(root.getRight(), search, 2) : false;
   if(!isInLeftTree && !isInRightTree ){
    path.pop();
    return false;
   }
   return true;
  }
 }
Read the downward element and create for these downward element.
List 4
 private List downwardElements(PathElement elem, int distance) {
  List chars = new LinkedList();
  return readElementAtDistanceK(chars, elem.node, distance);
  //Following method is listed further.
 }
Read the upward elements and add them to the list created above.
List 5
 private List upward(Stack path, PathElement pathElem, int distance) {
  PathElement prevElement = pathElem;
  PathElement element;
  int count = 1;
  List chars = new LinkedList();
  try{
   while( ( element = path.pop() ) != null){
    readElementsInDifferentDirection(chars, element, distance - count, prevElement.direction);
    prevElement = element;
    count++;
   }
  }catch(EmptyStackException ese){
  }
  return chars;
 }

 private List readElementsInDifferentDirection(List chars, PathElement element, int i, int direction) {
  Tree root = element.node;
  if( i == 0 ){
   chars.add(root.data);
  }
  if( direction == 1 ){
   readElementAtDistanceK(chars, root.right, i - 1 );
  }else{
   readElementAtDistanceK(chars, root.left, i - 1 );
  }
  return chars;
 }
Module to Read all the elements at a distance K from a node.
List 6
 private List readElementAtDistanceK(List chars, Tree root, int distance) {
  if( root == null ) return chars;
  if( distance == 0 ){
   chars.add(root.data);
   return chars;
  }
  readElementAtDistanceK(chars, root.left, distance - 1 );
  readElementAtDistanceK(chars, root.right, distance - 1 );
  return chars;
 }
Java representation to call the module is as followed.
List 7
  tp.searchElement(root, search, 0);
  PathElement pathElem = tp.path.pop();
  List<Character> chars = tp.downwardElements(pathElem, distance);
  chars.addAll(tp.upward(tp.path, pathElem, distance));  
  System.out.println("All the Characters:" + chars);
It will contain few generic related warnings and errors, please modify them to compile and run the program.

This approach has space complexity of log(n) and time complexity as defined below.
Search the node and path = O(n) //Worst case scenario.
Search the downward and upward elements = O(n) //Worst case scenario.
Time complexity of algorithm is O(n).

Friday, January 17, 2014

Interview: Java along with Algorithm 3

First F2F was followed with another rounds of F2F. Though first round was 90 minutes long but this round did not last longer than 40 minutes.

  1. How to save key and list of Integers in the HashMap?
  2. How is it possible to reduce the size of this map?
  3. Implement HashMap?
  4. Implement LRU with the help of Map?
  5. Find all possible strings of a Given String?
I have got few more interviews lined up for next couple of days. So I will try to remember post those interview question.

In addition to posting new questions, I will surely post the answers these questions.

Interview: Java along with Algorithm 2

After clearing questions in the first round, I was asked to face the interviewer in F2F rounds. I was nervous to face the interviewers after a long long time.

It all started with the general introductory question and followed with the following questions.
  1. Difference between Restful and Soap web services?
  2. What is Soap WS?
  3. Which different XML parsers we have?
  4. Write code for stream parser?
  5. Tell me the class loader heirarchy?
  6. What is serialization?
  7. What is SerialVersionUID?
  8. How does Hashmap work?
  9. What are the differences between SynchronizedHashMap and ConcurrentHashMap?
  10. Implement stack using 2 queues?
  11. Implement stack using 1 queue?
  12. Sort an array containing numbers 0,1,2?
  13. Difference between abstraction and encapsulation?
  14. where will you categories the private method?
  15. How to stop subclass from serializing if super-class is serializable?
I will try to post answers to following question within some time.

Tuesday, January 7, 2014

Interview: Java along with Algorithm

Few days back, I faced a telephonic interview with a Product based company in Gurgaon. It was quite a quick interview round for me. Here I am mentioning the questions asked by interviewer.


So Linked list provides following two advantages over arrays
1)         Dynamic size
2)         Ease of insertion/deletion
Linked lists have following drawbacks:
1)         Random access is not allowed. We have to access elements sequentially starting from the first node. So we cannot do binary search with linked lists.
2)         Extra memory space for a pointer is required with each element of the list.
3)         Arrays have better cache locality that can make a pretty big difference in performance. 

Q3. Suggest the best possible data structure in these 2 conditions?
A. DS must have add, delete, search operations, where search is most used functions of the DS?
DS based on hashing technique.
B. DS must have add, delete, rangeSearch operations, where search is most used functions of the DS?
DS based on Tree technique.

Q4. What do you mean by Hashing?
Q5. What are the different algorithms to resolve hash collision?
Q6. Is it possible to call static method within a constructor?
Q7. What is synchronization?
Q8. What are the different ways of implementing Threads?

Q9. What is the difference between creating threads by implementing runnable Interface or extending thread class implementation?
Implements Runnable is the preferred way to do it, IMO. You're not really specializing the thread's behaviour. You're just giving it something to run. That means composition is the philosophically "purer" way to go.

In practical terms, it means you can implement Runnable and extend from another class as well.

Q10. What is the difference between Callable and Runnable interfaces?
The Callable interface is similar to Runnable, in that both are designed for classes whose instances are potentially executed by another thread. A Runnable, however, does not return a result and cannot throw a checked exception.

Q11. What is garbage collection?
Q12. What is the difference between notify and notifyAll()?

Q13. What are practical scenarios where notify and notifyAll work?

Saturday, January 4, 2014

Algorithm: Find smallest contiguous array containing K 0's in array of 1's and 0's

I was thinking to improve my algorithmic fundamentals, so I planned to make few notes for myself that will assist me in future (Obviously at the time of Interviews). Following questions and answers have been taken from stackoverflow.com. This post is a sticky notes post for me. Please do not use the answers for reference purpose.

Following question was asked to me in an telephonic discussion with some interviewer. I had posted the question on stackoverflow where people provided me a satisfactory and efficient solution.

Problem Statement
I have array of 1's and 0's only. Now I want to find smallest contiguous subset/subarray which contains at least K 0's.

Example:
1 1 0 1 1 0 1 1 0 0 0 0 1 0 1 1 0 0 0 1 1 0 0 1 0 0 0
K(6) is either 0 0 1 0 1 1 0 0 0 or 0 0 0 0 1 0 1 1 0.

We have to come up with the solution where algorithm must minimize the number of iterations.

Algorithm
  • In the given array, find the first occurance of 0 (say at index i).
  • Keep on scanning until you've k 0's included in your window (say, the window ends at index j) Record the window Length(say j-i+1=L).
  • Discard the left-most 0 at index i, and keep scanning till you get next 0 (say at index i').
  • Extend the right-end of the window situated at j to j' to make the count of 0's = k again.
  • If the new window-length L'=j'-i'+1 is smaller update it.
Following algorithm does not take care about the boundary conditions and all, but this can be applied to the example mentioned above.

Iteration
  1. i = 3, String for K(6) 0 1 1 0 1 1 0 0 0 0, so j = 12, and l = 10.
  2. i = 6, String for K(6) 0 1 1 0 0 0 0 1 0, so j = 14, and l = 9. Update
  3. i = 9, String for k(6) 0 0 0 0 1 0 1 1 0, so j = 17, and l = 9. Donot update
  4. i = 10, string for k(6) 0 0 0 1 0 1 1 0 0, so i = 18, and l = 9. Do not update
  5. i = 11, String for k(6) 0 0 1 0 1 1 0 0 0, so I = 19, and l = 9; Do not update
  6. i = 12, String for K(6) 0 1 0 1 1 0 0 0 1 1 0, so I = 22, and l = 11, do not update
  7. i = 14, String for K(6) 0 1 1 0 0 0 1 1 0 0, so I = 23, and l = 10, do not update
  8. i = 17, String for K(6) 0 0 0 1 1 0 0 1 0, so I = 25, and l = 9, do not update
  9. i = 18, String for K(6) 0 0 1 1 0 0 1 0 0, so I = 26, and l = 9, do not update
  10. i = 19, String for K(6) 0 1 1 0 0 1 0 0 0, so I = 27, and l = 9, do not update
No more iteration is available. So first string which has 6 o's and has the minimum length is selected from the array set.

Java Program
package com.number;

public class MinimumStringContainingKZeros {
 
 public String minStrHavingKZeros(String str, int k){
  int i = find(str, 1, 0);
  int j = find( str, k - 1, i + 1 );
  System.out.println( i + " && " + j);
  if( i == -1 || j == -1 ) return "";
  int i1 = i;
  int j1 = j;
  while(true){
   i1 = find(str, 1, i1 + 1);
   j1 = find(str, 1, j1 + 1);
   if( j1 == -1 ) break;
   if( j1 - i1 < j - i ){
    i = i1;
    j = j1;
   }
  }
  return str.substring(i, j + 1);
 }
 
 int find(String str, int count, int start){
  int index = start;
  while( index < str.length() ){
   if( str.charAt(index) == '0'){
    count --;
    if( count == 0 ){
     return index;
    }
   }
   index++;
  }
  return -1;
 }
}

Time Complexity
Appllication has to run through the whole characters twice, once to find the first element and another to last element.
O(n) is the time complexity of the application.

Space Complexity
No additional space is required in this algorithm.

Friday, September 16, 2011

Immutable Classes

Class whose instance object can not be modified are called immutable classes. In Java, Strings are best example of immutable classes. Though Java tackles Strings in differently manner but still they maintain the immutability of String class. In more technical terms, Immutable object are the objects whose state can not be changed.

What is the state of the object?
State of the object is value of its fields.

public class User {
String firstName;
String lastName;
public User(String firstName, String lastName, int identitiNumber) {
this.firstName = firstName;
this.lastName = lastName;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}

If you create instance of User class with Java as first name and Developer as last name, then userObject state is Java Developer.

But later you can change the last name to Programmer. So latest state would be Java Programmer. So in this case our class is mutable and it can alter the state based on the requirement.

What is an Immutable Object?
As mentioned earlier object whose state can not be altered is immutable object.

In Effective Java, Joshua Bloch makes this compelling recommendation :
"Classes should be immutable unless there's a very good reason to make them mutable....If a class cannot be made immutable, limit its mutability as much as possible."

How to create Immutable object/class?
To create immutable object prototype should be such that it should not provide a way to change the value once object has been created. Sun has defined one contract which should be followed to create immutable classes. Sun Immutable class contract.

Remove the setter methods.

public class User {
String firstName;
String lastName;
public User(String firstName, String lastName, int identitiNumber) {
this.firstName = firstName;
this.lastName = lastName;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
}

Lets analyze if this solution will make the class immutable completely. Actually it will not. Because by default fields are visible to the class existing in same package. firstName and lastName are still exposed to classes in the same package. So it is still not safe.

Make all fields as private to the class


public class User {

private String firstName;

private String lastName;

public User(String firstName, String lastName, int identitiNumber) {

this.firstName = firstName;
this.lastName = lastName;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
}

Looks like we are safe now. But it does not look like. Though in our strings are immutable objects but lets say firstname and lastname are mutable objects. Then some one can take the reference of the object and change its property. So to by pass this problem, we will not return reference of the object but we will return cloned object.

Get should return cloned object


public class User {

private String firstName;

private String lastName;

public User(String firstName, String lastName, int identitiNumber) {

this.firstName = firstName;
this.lastName = lastName;
}
public String getFirstName() {
return firstName.clone();
}
public String getLastName() {

return lastName.clone();

}

}



Make the class prototype final and all the final


Seems like class is safe and will do great. But to secure class/code secure from security threats and reflection uses we should mark class and its fields final. Generally class is marked as final so that any developer should not create any mutable class extending immutable class. If you are leaving this class non-final then java docs should provide basic purpose of leaving this non-final, so that developer extending the class should be sure about the complete feature of the class. For more information

Make the class prototype final and all the final


public final class User {
private final String firstName;
private final String lastName;
public User(String firstName, String lastName, int identitiNumber) {
this.firstName = firstName;
this.lastName = lastName;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
}

What are the advantages of Immutable object?
Okay, I have created immutable object. What next? How will it help me to improve my application? There are lot of questions that bugged me after creating first real immutable object. I search a little bit and most of the places suggest me thread safety is the biggest advantage of immutable classes. Lets figure out all possible advantage of immutable classes over mutable classes.

Thread Safe
When threads are sharing objects then it is mandatory to synchronize the shared object when state of shared object is changed by . In case of immutable objects we do not have any ways with which state of the shared object can be modified. So if multiple threads are sharing the same object, even then we do not have to worry about changes in shared data. As data for all the threads will remain consistent so there will not be any reading issues. So while writing thread code, we can use immutable object without any issue.

As immutable objects do not need additional protection at the time of thread handling, so additional efforts of synchronization will be by-passed. So application will become little faster than synchronized application.

Simple to construct, test, and use
Due to immutable behaviour of the object, these object are less error prone and can be tested easily. They are safe in threads so there are less complexity involved with the threads.

Do not need a copy constructor and clone
It is not required to create copy constructor for any immutable classes, because reference of the class will solve the purpose of copying.
For mutable classes copy constructor creates the copy of the existing object and later this copy can be altered as per the business need. Whereas in case of Immutable object user can not change the object, so instead creating the same object again, it is more advisable to return the same object.

Allow hashCode to use lazy initialization, and to cache its return value
Lazy initialization is the process to delay the process of instantiate/process something until it is necessary. So in case of immutable objects compiler need not to use hash code operation for each and every object until it is necessary. As hash code of the object will not change until the object remains in the memory, so hash code for the object can be cached for future references.

Do not need to be copied defensively when used as a field
It is not required to copy all the fields of the immutable object. As everything is unshakable so it is okay to return the reference of the object instead copying it deeply.

Make good Map keys and Set elements
As caching of the object's hashcode is possible so it makes better performing Maps and sets which internally uses hashing for faster access.

Always have failure atomicity
The transaction subtracts 10 from A and adds 10 to B. If it succeeds, it would be valid, because the data continues to satisfy the constraint. However, assume that after removing 10 from A, the transaction is unable to modify B. If the database retains A's new value, atomicity and the constraint would both be violated. Atomicity requires that both parts of this transaction complete or neither.

If an immutable object throws an exception, it's never left in an undesirable or indeterminate state.

What are the disadvantage of Immutable object?
So many advantage, then why caring about disadvantage. Why does every java developer not make all classes immutable? Why do we need mutable class when immutable are solving all the earthly and programmatic complexities. Anyways I believe we should know it. Following are few problematic areas of immutable objects.

Memory requirement

With immutability, any time you need to modify data, you need to create a new object. This can be expensive. Imagine needing to modify one bit in an object that consumes several megabytes of memory: you would need to instantiate a whole new object, allocate memory, etc. If you need to do this many times, mutability becomes very attractive.
Conclusion
As it is evident immutable object has lot of advantage over mutable object.Immutable objects (and more particularly, immutable collections) avoid all of these problems. Once you get your mind around how they work, your code will develop into something which is easier to read, easier to maintain and less likely to fail in odd and unpredictable ways. Immutable objects are even easier to test, due not only to their easy mock ability but also the code patterns they tend to enforce. In short, they're good practice all around!

Source/References(Used to write this post)


http://www.javalobby.org/articles/immutable/index.jsp

http://www.informit.com/articles/article.aspx?p=20530

http://www.javapractices.com/topic/TopicAction.do?Id=29

http://www.ibm.com/developerworks/java/library/j-jtp04223/index.html
http://www.javaranch.com/journal/2003/04/immutable.htm
http://www.javalobby.org/articles/immutable/index.jsp
http://www.ibm.com/developerworks/java/library/j-jtp02183/index.html
http://en.wikipedia.org/wiki/Immutable_class
http://stackoverflow.com/questions/5652652/java-advantages-of-of-immutable-objects-in-examples

Friday, August 5, 2011

Java: Pass by Value

I was in an interview and interviewer asked me the following question.

public static void main(){
          String s1 = "A";
          s1 = s1 + 1;
          System.out.println("Before function call S1 is:" + s1);
          modifyString(s1);
          System.out.println("After function call S1 is:" + s1);
}

String modifyString(String a){
          a = a + 2;
          return a;
}

What is the output of the following problem?

Though I knew Java is pass by value but at the time of function call Java passes memory reference of the objects. So with the conviction I wrote the output of the program.

Before function call S1 is: A1
After function call S1 is: A12

Interview was over, I returned home, wrote the program and ran it in my eclipse. Bomb... It exploded. Results were not as I expected. WTF, why are those results not the same as I expected? I am the Java bond I can not be wrong. Instantaneously I pinged for an assistance. I wanted to hear "there is a problem with my eclipse instance. I should dump the current eclipse and take the latest eclipse soon." But instead hearing those words  I got following response.

Before function call S1 is: A1
After function call S1 is: A1

My expectation were shattered and I started arguing. Argument ended with my broken believe and I figured out "I have to cover a lot more about java fundamentals".

Anyways let me tell  you how does java pass the object to the function. In general java do not differentiate between Objects and primitive data type. It uses copy operation to pass the value of both type of data types.
If you have overridden copy method of your class then java will copy the object based of your implementation otherwise it will copy the object shallowly, in other words we say java uses shallow copy functionality of the objects. In case of shallow copy it creates a new reference to the object passed to the method. Now whenever you change in this method, are reflected back in the mutable classes, whereas in case of immutable classes it is not possible to change the object so we refrain ourselves to changing anything in those classes.

Lets review the following program.


public class PassByValueInJava {

int xy = 0;
private static void modifyPav(PassByValueInJava pav3 ,PassByValueInJava pav4) {
int temp  = pav3.xy;
pav3.xy = pav4.xy;
pav4.xy = temp;
}

public static void main(String[] args) {
PassByValueInJava pav1 = new PassByValueInJava();
PassByValueInJava pav2 = new PassByValueInJava();
pav1.xy = 10;
pav2.xy = 20;
System.out.println("Before Modify:::: pav1 x:" + pav1.xy + "   pav2 x:" + pav2.xy);
modifyPav(pav1, pav2);
System.out.println("After Modify::::pav1 x:" + pav1.xy + "   pav2 x:" + pav2.xy);
}

}


Can you guess what is the output of the program written here?
After seeing the above example I thought it should not switch the values. So results should be the following
Before Modify:::: pav1 x:10 pav2 x:20
After Modify:::: pav1 x:20 pav2 x:10

Now it is strange. Why did swapping happened? Was there something different?

Okay, lets analyze what has happened in this program? Main function calls the modify function and providing them the copy of pav1 and pav2. As copy is a shallow copy, so in this case Java will create a reference which will point to the same memory location of the previous object. Memory location depicts the situation well here.

Why did not same thing happened when string object was passed to the method.
As string in java are immutable so java deals with string in a different manner. Initially when S1 = A then string was pointing to one memory location and as soon as S1 = S1 + 1, it creates new string object and S1 was assigned to it.

Now when Main called modify function s1 was pointing to A1 memory location whose reference was passed to modify function. When string s2 got changed, then it started pointing to the A12 string object's memory location. But s1 is still pointing to the A1 string object's memory location. That is why value for s1 did not modify.

So it is clear that java always uses pass by value and as java tackles string in a complete different way, this is the reason we see such a huge difference between objects and strings.

Program mentioned above could enhance with the following


public static void main(){
          String s1 = "A";
          s1 = s1 + 1;
          System.out.println("Before function call S1 is:" + s1);
          s1 = modifyString(s1);
          System.out.println("After function call S1 is:" + s1);
}

String modifyString(String a){
          a = a + 2;
          return a;
}

It will result in the expected output.