Friday, May 9, 2014

Construct Tree from given Inorder and Preorder traversals

Problem:
Give two strings representing the inorder and preorder traversals of binary tree, construct the tree.

The key here is that preorder traversal, the first char is the tree root. And then based on that char, find the its position in inorder string, then its left portion of in order string is the left subtree, right portion is the right subtree.

And do it recursively, make it simpler.


public static Node constructTree(String pre, String in){
if(pre.isEmpty())
return null;
if(pre.length() == 1)
return new Node(pre.charAt(0));
Node root = new Node(pre.charAt(0));
String[] ins = splitStringBy(in, pre.charAt(0));
                root.left = constructTree(pre.substring(1, ins[0].length()+1), ins[0]);
root.right = constructTree(pre.substring(ins[0].length()+1), ins[1]);
return root;
}
public static String[] splitStringBy(String str, char root){
String[] re = new String[2];
re[0] = str.substring(0, str.indexOf(root));
re[1] = str.substring(str.indexOf(root)+1);
return re;
}


Find the maximum sum from leaf to root in a binary tree

Given a Binary Tree, find the maximum sum from a leaf to root and return this leaf as well.


The key is from root to leave, add up the node value and pass the sum to the lower levels. 


public static int maxSumFromRootHelper(Node root, int sum){
if(root == null)
return sum;
else{
return Math.max(maxSumFromRootHelper(root.left, root.data + sum),
  maxSumFromRootHelper(root.right, root.data + sum));
}
}

//store the max sum result
static int max_sum = Integer.MIN_VAL;
//store the leaf 
static Node maxNode = null;
public static void findLeaveWithMaxSumFromRoot(Node root, int sum){
if(root == null)
return;
sum = sum + root.data;
if(root.left == null && root.right ==null){
if(sum > max_sum){
max_sum = sum;
maxNode = root;
}
}
else{
findLeaveWithMaxSumFromRoot(root.left, sum);
findLeaveWithMaxSumFromRoot(root.right, sum);
}
} 

divide number and return result in a string

This is a google interview question: 

Divide number and return result in form of a string. e.g 100/3 result should be 33.(3) Here 3 is in brackets because it gets repeated continuously and 5/10 should be 0.5.

Here is my attempt, the key is to doing module and division, also figure out how many 0s are there after decimal point. 




public static String divideToString(int num1, int num2){
    int d = num1/num2;
    int m = num1%num2;
    boolean flag = false;
    Set<Integer> seen = new HashSet<Integer>();
    StringBuilder sb = new StringBuilder();
    sb.append(d);
    while(m!=0){
    if(!flag){
        sb.append(".(");
        flag = true;
    } 
     
    num1 = m*10;
    d = num1/num2;
    m = num1%num2;
       
    if(seen.contains(num1)){
    sb.append(")");
    break;
    }else{
    sb.append(d);  
    seen.add(num1);
    }
    }
   
    return sb.toString();
}

Wednesday, April 30, 2014

Permutations for digits represented by Phone Number

This is a stackoverflow question: http://stackoverflow.com/questions/1851239/permutations-for-digits-represented-by-phone-number

This can be done by dynamic programming and just need to keep track of the previous result list and build result based on it.


public static List<String> allWordsFromPhonePad(int number){
HashMap<Integer, String > h = new HashMap<Integer, String>(){{
        put(1,"");
        put(2, "ABC");
        put(3, "DEF");
        put(4, "GHI");
        put(5, "JKL");
        put(6, "MNO");
        put(7, "PQRS");
        put(8, "TUV");
        put(9, "WXYZ");
        put(0, "");
    }};
    List<String> result = new ArrayList<String>();
    result.add("");
    while(number>0){
    int last = number%10;
    List<String> temp = new ArrayList<String>();
   
    for(String s: result){
    String map = h.get(last);
    for(char c : map.toCharArray()){
    temp.add(String.valueOf(c) + s);
    }
    }    
    number = (number-last)/10;
    if(!temp.isEmpty())
    result = temp;
    }
   
    return result;
}

Print all valid combinations of n-pairs of parentheses

For example, if n=1
{}
for n=2
{}{}
{{}}

Most of the solutions found online are using recursion. Here is the version which does iterative. 

The key is to keep track of the number of open parentheses, if there are open ones left, then add it to, also if number of open parentheses is bigger than close ones, then add close parentheses as well.


public static void allParenthesis(int k){
Map<String, Integer> list = new HashMap<String, Integer>();
list.put("(", 1);
for(int i = 1 ; i < k*2; i++){
Map<String, Integer> temp = new HashMap<String, Integer>();
for(String s : list.keySet()){
int left = list.get(s);
int right = s.length() - left;
if(left<k){
temp.put(s + "(", left+1); 
}
if(left>right){
temp.put(s + ")", left);
}
}
list = temp;
}
for(String s: list.keySet())
System.out.println(s);
}

Monday, April 28, 2014

Find the row with maximum number of 1s

This is from the geeksforGeeks site:


Given a boolean 2D array, where each row is sorted. Find the row with the maximum number of 1s.
Example
Input matrix
0 1 1 1
0 0 1 1
1 1 1 1  // this row has maximum 1s
0 0 0 0

Output: 2

The solution is simple. for each row, we will start from the end and move backwards until 0 is found. and the starting position for each row is equal to the previous row's starting position of 1. 

public static int findMaxOnes(int[][] nums){
int max = nums[0].length-1;
int index = 0;
for(int i = 0; i<nums.length; i++){
for(int j = max; j>=0; j--){
if(nums[i][j]==0)
break;
max = j;
index = i;
}
}
return index;
}

Saturday, April 26, 2014

In place sort of an array of numbers by zero


Problem:
  Given an array that has positive numbers and negative numbers and zero in it. 
 You need to seperate the negative numbers and positive numbers in such a way that 
 negative numbers lies to left of zero 
  and positive numbers to the right and the original order of elements should be maintained
This essentially is insertion sort algorithm with different comparison criterion. 


public static void orderByZero(int[] num){
for(int i = 1 ; i< num.length; i++){
int j = i ;
while(j>0){
if((num[j]<0 && num[j-1]>=0) || (num[j]==0 && num[j-1]>0)){
int t = num[j];
num[j] = num[j-1];
num[j-1] = t;
j--;
}else{
break;
}
}
}
}