AdSense

Showing posts with label Recursion. Show all posts
Showing posts with label Recursion. Show all posts

Wednesday, August 26, 2015

Scala note 1: Pascal’s Triangle, Parentheses Balancing and Counting Change

I decided to take a look on Scala, so that next time I read a source code, at least I know what I am reading.

I choose Coursera's Functional Programming Principles in Scala as my reference (I do wish they open the class again, however, the same time when they open the class last year, I was fighting with Java ðŸ˜ž.)

First week's class are basics. Two concepts need to be remember:

Call by value: evaluates function arguments before calling the functionCall by name: evaluates the function first, and then evaluate the arguments if needed
Scala usually do call by value, but we can also do call by name by adding x: => Type to the parameter. 
All three exercise problems are about recursions. The algorithms are easy since those are problems we see all the time. 

Pascal's Triangle
The numbers at the edge of the triangle are all 1, and each number inside the triangle is the sum of the two numbers above it. Write a function that computes the elements of Pascal’s triangle by means of a recursive process.Do this exercise by implementing the pascal function in Main.scala, which takes a column c and a row r, counting from 0 and returns the number at that spot in the triangle. For example, pascal(0,2)=1pascal(1,2)=2 and pascal(1,3)=3.def pascal(c: Int, r: Int): Int

def pascal(c: Int, r: Int): Int = {
    if  (c == 0 || c == r || r == 0)  1
    else
      pascal(c - 1, r - 1) + pascal(c, r - 1)
  }

Sort of short...


Parentheses Balancing
Write a recursive function which verifies the balancing of parentheses in a string, which we represent as a List[Char] not a String. For example, the function should return true for the following strings:
  • (if (zero? x) max (/ 1 x))
  • I told him (that it’s not (yet) done). (But he wasn’t listening)
The function should return false for the following strings:
  • :-)
  • ())(
The last example shows that it’s not enough to verify that a string contains the same number of opening and closing parentheses.Do this exercise by implementing the balance function in Main.scala. Its signature is as follows:def balance(chars: List[Char]): Boolean
def balance(chars: List[Char]): Boolean = {
    def balance(chars: List[Char], left: Int): Boolean ={
      if(chars.isEmpty) left == 0
      else
        if (chars.head == ')') {left > 0 && balance(chars.tail, left - 1)}
        else if (chars.head == '(') {balance(chars.tail, left + 1)}
        else {balance(chars.tail, left)} 
    }
    balance(chars, 0)
  }

Basically, we count the left parenthesis ("(") . Each time there is a "(", we increment left. If there is a ")" and if left >0, then it is imbalanced, otherwise decrease left and check the substring. 

Counting Change
Write a recursive function that counts how many different ways you can make change for an amount, given a list of coin denominations. For example, there are 3 ways to give change for 4 if you have coins with denomiation 1 and 2: 1+1+1+1, 1+1+2, 2+2.Do this exercise by implementing the countChange function in Main.scala. This function takes an amount to change, and a list of unique denominations for the coins. Its signature is as follows:def countChange(money: Int, coins: List[Int]): Int


def countChange(money: Int, coins: List[Int]): Int = {
    def countChange(money:Int, coins: List[Int], count:Int): Int = {
      if (money < 0) count
      else
        if (coins.isEmpty) 
          if (money == 0) count + 1 else count
        else
          countChange(money - coins.head, coins, count) + countChange(money, coins.tail, count)
    }
    countChange(money, coins, 0)
  }

To count all possibilities, we need to iterate all denominations in coins. Using recursion, it is the count of using coins[0] plus the count of not using coins[0], and recursively check all the denominations.


Source on git

Tuesday, March 10, 2015

Integer to String


"write a function that has an int as input and return the equivalent String as an output


12 -> 'twelve'
4345 -> 'four thousand three hundred and forty-five'
7654567643 -> 'seven billion six hundred and fifty-four million five hundred and sixty-seven thousand six hundred and forty-three'"

I parse the integer to a string thus we can use recursion to solve the problem. Given any integer, 
1, 111, 111, 111
The rule follows XXX billion XXX million XXX thousand and XXX, where XXX is in hundred, for example, one hundred and eleven. 
For numbers less than 20, the nomination is different, so we need to store each corresponding string in the map separately, for numbers larger than 20, store the tenth, e.g., thirty, forty, etc. We don't need to store hundred since it will be X hundred, where X is already in the map, and XX, which is a two digit number, and we can use recursion to get that. 
The code could be neater, I just don't have enough time to clean it. 

import java.util.*;
public class IntegerToString {
 private static Map numbers;
 static{
  numbers = new HashMap ();
  numbers.put(0, "zero");
  numbers.put(1, "one");
  numbers.put(2, "two");
  numbers.put(3, "three");
  numbers.put(4, "four");
  numbers.put(5, "five");
  numbers.put(6, "six");
  numbers.put(7, "seven");
  numbers.put(8, "eight");
  numbers.put(9, "nine");
  numbers.put(10, "ten");
  numbers.put(11, "eleven");
  numbers.put(12, "twelve");
  numbers.put(13, "thirteen");
  numbers.put(14, "fourteen");
  numbers.put(15, "fifteen");
  numbers.put(16, "sixteen");
  numbers.put(17, "seventeen");
  numbers.put(18, "eighteen");
  numbers.put(19, "nineteen");
  numbers.put(20, "twenty");
  numbers.put(30, "thirty");
  numbers.put(40, "forty");
  numbers.put(50, "fifty");
  numbers.put(60,"sixty");
  numbers.put(70, "seventy");
  numbers.put(80, "eighty");
  numbers.put(90, "ninety");
  
 }
 public static String read(int n){
  return read(String.valueOf(n));
 }
 public static String read(String nStr){
  int len = nStr.length();
  if(len < 2)
   return numbers.get(Integer.parseInt(nStr));
  else if(len < 3) {
   int tenth = Character.getNumericValue(nStr.charAt(0)) * 10;
   if (tenth == 0)
    return read(nStr.substring(1));
   if(tenth < 20)
    return numbers.get(Integer.parseInt(nStr));
   int single = Character.getNumericValue(nStr.charAt(1));
   return single == 0 ? numbers.get(tenth) : numbers.get(tenth) + "-" + numbers.get(single);
  }
  else if(len < 4){
   if(Integer.parseInt(nStr) == 0)
    return "";
   int hund = Character.getNumericValue(nStr.charAt(0));
   if(Integer.parseInt(nStr.substring(1)) == 0)
    return numbers.get(hund) + " hundred";
   return hund == 0 ? read(nStr.substring(1)) : numbers.get(hund) + " hundred and " + read(nStr.substring(1));
  }
  else if(len < 7){
   if(Integer.parseInt(nStr) == 0)
    return "";
   return read(nStr.substring(0, len - 3)) + " thousand " + read(nStr.substring(len - 3, len));
  }
  else if(len < 10){
   if(Integer.parseInt(nStr) == 0)
    return "";
   return read(nStr.substring(0, len - 6)) + " million " + read(nStr.substring(len - 6, len));
  }
  else
   return read(nStr.substring(0, 1)) + " billion " + read(nStr.substring(1));
 }
 public static void main(String[] args) {
  System.out.println(read(1));
  System.out.println(read(11));
  System.out.println(read(100));
  System.out.println(read(1000));
  System.out.println(read(1111));
  System.out.println(read(10000));
  System.out.println(read(11111));
  System.out.println(read(1000000));
  System.out.println(read(1111111));
  System.out.println(read(10000000));
  System.out.println(read(11111111));
  System.out.println(read(100000000));
  System.out.println(read(111111111));
  System.out.println(read(1000000000));
  System.out.println(read(1111111111));
  System.out.println(read(4345));
 }
}

Tuesday, March 3, 2015

Gray code

The gray code is a binary numeral system where two successive values differ in only one bit.
Given a non-negative integer n representing the total number of bits in the code, print the sequence of gray code. A gray code sequence must begin with 0.
For example, given n = 2, return [0,1,3,2]. Its gray code sequence is:
00 - 0
01 - 1
11 - 3
10 - 2
Note:
For a given n, a gray code sequence is not uniquely defined.
This problem is not a special one. Typical recursion follows Gray code rules. If n = 1, put 0 and 1 into the list and return. From n = 2, get grayCode(n - 1). Reverse the list ((0, 1) -> (1, 0)), add the reversed list by 1 << (n - 1), (1, 0) -> (11, 10), add the reversed list to the rst list and we are done!


public List grayCode(int n) {
        List rst = new ArrayList ();
        if (n <= 1){
            for(int i = 0; i <= n; i++)
                rst.add(i);
                return rst;
        }
        List reverseRst = grayCode(n - 1);
        rst = new ArrayList(reverseRst);
        Collections.reverse(reverseRst);
        int x = (1 << (n - 1));
        for(int i = 0; i < reverseRst.size(); i++){
            reverseRst.set(i, reverseRst.get(i) + x);
        }
        rst.addAll(reverseRst);
        return rst;
    }

Friday, February 27, 2015

Number of ways to make changes


Given an infinite number of quarters (25 cents), dimes (10 cents), nickels (5 cents) and pennies (1 cent), write code to calculate the number of ways of representing n cents.
Assume we need 25 cents, and we want to  make changes, how can we do it?

Naturally, we will think of first, get 1 quarter
1. 25cents
Since we only need 25 cents, so at most 1 1 quarter will be used. Then we will think of the next largest domination, dime
2. 10 + 10 + 5
Because we want to add up all coins to 25
Then we further split 1 10 cent to to 5
3. 10 + 5 + 5 + 5
Then we use all 5 cents
4. 5 + 5 + 5 + 5 +5

So each time we use one domination, and find next needed coins based on the cents left, and we can do it recursively.



public class RepresentCents {
 public static int makeChange(int n) {
  return ways(n, 25);
 }
 public static int ways(int n, int denom){
  int next_denom = 0;
  //find the next largest denomination
  switch(denom) {
  case 25:
   next_denom = 10;
   break;
  case 10:
   next_denom = 5;
   break;
  case 5:
   next_denom = 1;
   break;
  //after we use the smallest denomination,
  //we need to check if all coins have added up to 
  //the desired cents, if they have, return 1 way
  //otherwise return 0 ways
  case 1:
   if (n == 0)
    return 1;
   else
    return 0;
  }
  int ways = 0;
  //check all number of coins can be used in current denomination
  for (int i = 0; i * denom <= n; i++){
   ways += ways(n - i * denom, next_denom);
  }
  return ways;
 }

 public static void main(String[] args) {
  System.out.println(makeChange(30));

 }

}

Wednesday, January 21, 2015

Regular Expression Match II

The first one is a LeetCode problem, and can be found here.

This one, is similar, with the only difference that now we need to take into account '+'. Here is the problem statement:

Write a Simple regex parser, where pattern can contain *, + or .
* -> 0 or none
+ -> one or more
. -> Exactly one character
Examples:
Input - Pattern = a*b+c. data= bcOutput - true
Input - Pattern - abc+ data=abcOutput - true
Input - Pattern - ab* data=c
Output - false

I will still use the recursion method as the first one. When the s.charAt(1) = '+', since there is at least one proceeding character needs to be matched, we need to check if s.charAt(0) == p.charAt(0) or p.charAt(0) == '.'. Moreover, if s is an empty string, it definitely means that they don't match, so simply return false. Now if the first character matches, we need to check how many characters are matched by '+'. I use a loop, if any character in s matches p.charAt(2) (e.g., bbbbbc, and b+c), recursively check the substring of s and p.

Update: 2015 - 03 - 18
I notice the code below has a mistake because I didn't understand regex. '+' matches the proceeding character one or more times, that means the format must be bbbbbc matches b+c, but bbbddc doesn't match b+c.

Here is the updated code.

public static boolean isMatch(String s, String p){
  if(s == null)
   return p == null;
  if(p == null)
   return false;
  if(p.length() == 0)
   return s.length() == 0;
  if(s.equals(p))
   return true;
  if(p.length() == 1 || (p.charAt(1) != '*' && p.charAt(1) != '+')){
   if(s.length() < 1 || (s.charAt(0) != p.charAt(0) && p.charAt(0) != '.'))
    return false;
   return isMatch(s.substring(1), p.substring(1));
  }
  if(p.charAt(1) == '+'){
   //must match at least once
   if(s.length() < 1 || (s.charAt(0) != p.charAt(0) && p.charAt(0) != '.'))
    return false;
   char match = s.charAt(0);
   int index = 0;
   while(index < s.length()){
    if(s.charAt(index) != match)
     break;
    index++;
   }
   return isMatch(s.substring(index), p.substring(2));
  }
  int index_s = -1;
  while(index_s < s.length() && (index_s < 0 || s.charAt(index_s) == p.charAt(0) || p.charAt(0) == '.')){
   if(isMatch(s.substring(index_s + 1), p.substring(2)))
    return true;
   index_s++;
  }
  return false;
 }


public static boolean isMatch(String s, String p) {
  if (p == null || s == null)
   return false;
  if (p.length() == 0)
   return s.length() == 0;
  if (p.equals(s))
   return true;
  if (p.length() == 1 || (p.charAt(1) != '*' && p.charAt(1) != '+')) {
   if (s.length() < 1 || (s.charAt(0) != p.charAt(0) && p.charAt(0) != '.'))
    return false;
   return isMatch(s.substring(1), p.substring(1));
  }
  if (p.charAt(1) == '+') {
   if (s.length() < 1 || (s.charAt(0) != p.charAt(0) && p.charAt(0) != '.')) {
    return false;
   }
   for (int i = 1; i <= s.length(); i++) {
    if (i < s.length() && p.length() > 2 && s.charAt(i) != p.charAt(2))
     continue;
    if (isMatch(s.substring(i), p.substring(2)))
     return true;
   }
   return false;
  }
  int index_s = -1;
  while (index_s < s.length() && (index_s < 0 || s.charAt(index_s) == p.charAt(0) || p.charAt(0) == '.')) {
   if (isMatch(s.substring(index_s + 1), p.substring(2)))
    return true;
   index_s++;
  }
  return false;
 }

Tuesday, January 20, 2015

Reverse a BST, find the kth largest element in BST

This is a FB interview question.
1. Reverse the BST;
2. find the kth largest element in O(n) time;
3. find the kth largest element in O(log n) time.

The first one is easy, recursively flip the left and right child of the tree.
The second one too, use in order traversal.
Now comes the third one. Here is an answer I found.
Here's just an outline of the idea:
Let each node in the BST have a field that returns the number of elements in its left and right subtree. Let the left subtree of node T contain only elements smaller than T and the right subtree only elements larger than or equal to T.
Now, suppose we are at node T:
  1. k == num_elements(left subtree of T), then the answer we're looking for is the value in nodeT
  2. k > num_elements(left subtree of T) then obviously we can ignore the left subtree, because those elements will also be smaller than the kth smallest. So, we reduce the problem to finding the k - num_elements(left subtree of T) smallest element of the right subtree.
  3. k < num_elements(left subtree of T), then the kth smallest is somewhere in the left subtree, so we reduce the problem to finding the kth smallest element in the left subtree.
This is O(log N) on average (assuming a balanced tree).

But the problem is, how to get the size of the tree? In the end, I wrote a Tree class. However, there is a bug in this class: I can only build the tree bottom up: otherwise the children of the subtree will not be added into the parent's children list.

import java.util.*;
public class Tree {
 private int size;
 TreeNode node;
 Tree left;
 Tree right;
 List children;
 public Tree() {
  children = new ArrayList();
  size = 0;
 }
 public Tree(int rootVal) {
  node = new TreeNode(rootVal);
  children = new ArrayList ();
  left = new Tree();
  right = new Tree();
  size++;
 }
 private void addChildren(Tree tree) {
  children.addAll(tree.children);
  size += tree.children.size();
 }
 public void buildLeft(Tree leftTree) {
  node.left = leftTree.node;
  left = leftTree;
  children.add(leftTree.node);
  size++;
  addChildren(leftTree);
 }
 
 public void buildRight(Tree rightTree) {
  node.right = rightTree.node;
  right = rightTree;
  children.add(rightTree.node);
  size++;
  children.addAll(rightTree.children);
  size += rightTree.children.size();
 }
 public int size() {
  return size;
 }

}
public class TreeNode {

  int val;
  TreeNode left;
  TreeNode right;
  //TreeNode parent;
  TreeNode(int x) { val = x;}

}


Here are the methods for the three problems:


public static void reverseBST (TreeNode root) {
  if (root == null || (root.left == null && root.right == null))
   return;
  TreeNode tmp = root.left;
  root.left = root.right;
  root.right = tmp;
  reverseBST(root.right);
  reverseBST(root.left);
 }
 static int count = 0;
 /**
  * O(n) complexity
  * @param root
  * @param k
  * @return
  */
 public static int kthLargest(Tree root, int k) {
  if (root == null)
   return -1;
  return findKth(root.node, k).val;
  
 }
 private static TreeNode findKth (TreeNode root, int k) {
  if (root == null)
   return root;
  TreeNode right = findKth(root.right, k);
  if (count == k)
   return right;
  ++count;
  if (count == k)
   return root;
  return findKth(root.left, k);
 }
 /**
  * O(log n) complexity
  * @param root
  * @param k
  * @return
  */
    public static TreeNode findKth(Tree root, int k) {
     if (root.right.size() == k - 1)
      return root.node;
     else if (root.right.size() < k - 1)
      return findKth(root.left, k - root.right.size() - 1);
     else
      return findKth(root.right, k);
  
 }

Monday, January 19, 2015

Isomorphic Trees

An easier version of Scramble String. Two trees are called isomorphic if one of them can be obtained from other by a series of flips, i.e., by swapping left and right children of a number of nodes. Two empty trees are isomorphic.

Image source: http://www.geeksforgeeks.org/tree-isomorphism-problem/
The above two trees are isomorphic because : 2 & 3, Null & 6, 7 & 8 are flipped.


public boolean isIsomorphic(TreeNode p, TreeNode q){
    if(p == null)
        return q == null;
    if(q == null)
        return false;
    if(p.val != q.val)
        return false;
    return (isIsomorphic(p.left, q.left) && isIsomorphic(p.right, q.right)) 
    || (isIsomorphic(p.left, q.right) && isIsomorphic(p.right, q.left));
}

Friday, January 9, 2015

Generate Parentheses

Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses.
For example, given n = 3, a solution set is:
"((()))", "(()())", "(())()", "()(())", "()()()"

Another recursion problem. Add "(" to the string, and decrease the total "(" number, when the number of left parenthesis and right parenthesis left both equal 0, add the string to rst list. If the number left parenthesis is larger than the right one, or either of them is less than 0, return.

public List generateParenthesis(int n) {
        List rst = new ArrayList ();
        if (n <= 0)
            return rst;
        getParenthesis("", rst, n, n);
        return rst;
    }
    private void getParenthesis(String p, List rst, int left, int right) {
        if (left > right || left < 0 || right < 0)
            return;
        if (left == 0 && right == 0) {
            rst.add(p);
            return;
        }
        getParenthesis(p + "(", rst, left - 1, right);
        getParenthesis(p + ")", rst, left, right - 1);
    }

Friday, January 2, 2015

Median of Two Sorted Arrays

There are two sorted arrays A and B of size m and n respectively. Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).

This problem is an implementation of the Find k-th smallest number in two sorted array .

Note that if the total number of elements of two arrays is odd, we need to find the( (A.length + B.length) / 2 + 1 )-th element. If it is even, we need to find that number and the number before that and take the average.

The following code compares between B[j - 1] and A[i], and thus reduces the comparison among B[j - 1], A[i] and B[j]. This may reduce couple lines of code. Yet the trade-off is that each time we only discard 1/4 of the total number of elements in each recursion, even though the solution can still be accepted.

I prefer to write couple more lines. :)



public class Solution {
    public double findMedianSortedArrays(int A[], int B[]) {
        if (A == null || B == null)
            throw new NullPointerException("Null array(s)!");
        if (A.length == 0 && B.length == 0)
            return 0.0;
        int len = A.length + B.length;
        if (len % 2 != 0)
            return (double)findMedian(A, 0, B, 0, len / 2 + 1);
        int r1 = findMedian(A, 0, B, 0, len / 2);
        int r2 = findMedian(A, 0, B, 0, len / 2 + 1);
        double rst = (double)(r1 + r2) / 2.0;
        return rst;
        
    }
    private int findMedian(int[] A, int A_start, int[] B, int B_start, int k) {
        if (A_start >= A.length)
            return B[B_start + k - 1];
        if (B_start >= B.length)
            return A[A_start + k - 1];
        if (k == 1)
            return Math.min(A[A_start], B[B_start]);
        //A_key = k / 2 - 1
        //B_key - 1 = k / 2 - 1
        int index_A = A_start + k / 2 - 1;
        int index_B = B_start + k / 2 - 1;
        int A_i = (index_A >= A.length) ? Integer.MAX_VALUE : A[index_A];
        int B_i = (index_B >= B.length) ? Integer.MAX_VALUE : B[index_B];
        if (A_i < B_i)
            return findMedian(A, index_A + 1, B, B_start, k - k / 2);
        else
            return findMedian(A, A_start, B, index_B + 1, k - k / 2);
    }
}

Update: 2015 - 01 - 15
I realize that if I use the code in the post Find k-th smallest number in two sorted array, it will exceed time limit.

Find k-th smallest number in two sorted array

The algorithm is explained here.

I will explain it briefly based on my understanding. Choose any index in array A, say i. Choose a corresponding index in array B, say j,  that maintain the equivalence i + j = k - 1. Then the k-th smallest element can be acquired if one of the following conditions is fulfilled:

1. if k == 1, return the smallest between the first elements in A and B;
2. if (B[j - 1] <= A[i] < B[j +1]), then return A[i].
3. if (A[i - 1] <= B[j] < A[i] ), then return B[j].

Condition 2 and 3 are similar, take 2 as the example.






If A[i] is between B[j -1] and B[j], and there are i elements before A[i] and j elements before B[j], and because k = i + j + 1, then A[i] is the k-th smallest element we are looking for. 

Well, life would be perfect if one of the above conditions can always be fulfilled, what if not? 

So, if A[i] is not greater than or equal to B[j -1], but A[i] is smaller than B[j], what does that imply? It means A[i] must also be smaller than B[j - 1], and since k = i + j + 1, it must not be in A[i] and all elements less than A[i]. Then we can discard that part of the array. (Switch j - 1 and i in the figure to make it easier to understand). Likewise, we may conclude that all elements larger than B[j] will also not be in the range.  Similarly, we can discard corresponding elements if B[j] is smaller than A[i]. Good, we just halve the total array. 

And the solution will get by... Recursion! 

I follow the author of my reference and choose i and j  based on the weights of the lengths of two arrays. Alternatively, we can choose k/2 or anything else as long as both i and j are smaller than the lengths of A and B. 







public class FindKthSmallest {
 public int findKth(int[] A, int[] B, int k) {
  if (A == null || A.length == 0 || B == null || B.length == 0 
    || k < 0 || k > A.length + B.length)
   throw new IllegalArgumentException("Invalid input!");
  return findKthSmallest(A, 0, A.length, B, 0, B.length, k);
 }
 public int findKthSmallest(int[] A, int A_start, int la, int[] B, int B_start, int lb, int k) {
  if (A_start >= A.length)
   return B[B_start + k - 1];
  if (B_start >= B.length)
   return A[A_start + k - 1];
  if (k == 1)
   return Math.min(A[A_start], B[B_start]);
  
  //choose index based on the weight of length of A and B
  int A_key = (int) ((double) la / (la + lb) * (k - 1));
  int B_key = (k - 1) - A_key;
  //note the actual index will be A_start + A_key
  int index_A = A_start + A_key;
  int index_B = B_start + B_key;
  //index_A == 0: la = 1; lb = 10; k = 3; index_A = (1/11 *3) = 0
  int A_i_1 = (index_A == 0) ? Integer.MIN_VALUE : A[index_A - 1];
  int B_j_1 = (index_B == 0) ? Integer.MIN_VALUE : B[index_B - 1];
  //index_A == la: la = 10; lb = 1; k = 11; index_A = 10/11 * 11 = 10
  int A_i = (index_A == la) ? Integer.MAX_VALUE : A[index_A];
  int B_j = (index_B == lb) ? Integer.MAX_VALUE : B[index_B];
  
  if (B_j_1 <= A_i && A_i < B_j) 
   return A_i;
  if (A_i_1 <= B_j && B_j < A_i)
   return B_j;
  //if A_i < B_j and apparently from above A_i is NO larger than B_j_1
  if (A_i < B_j) 
   //discard A_i and below
   //length = la - (index_A - A_start + 1) = la - A_key -1
   return findKthSmallest(A, index_A + 1, la - A_key - 1, B, B_start, B_key + 1, k - A_key - 1);
  else
   return findKthSmallest(A, A_start, A_key + 1, B, index_B + 1, lb - B_key - 1, k - B_key - 1);
  
 }
}

Wednesday, December 24, 2014

Sum of nested integers

/** 
* Given a nested list of integers, returns the sum of all integers in the list weighted by their depth 
* For example, given the list {{1,1},2,{1,1}} the function should return 10 (four 1's at depth 2, one 2 at depth 1) 
* Given the list {1,{4,{6}}} the function should return 27 (one 1 at depth 1, one 4 at depth 2, and one 6 at depth 3) 
*/ 
public int depthSum (List<NestedInteger> input) 
{ // ur implementation here} 


** 
* This is the interface that represents nested lists. 
* You should not implement it, or speculate about its implementation. 
*/ 
public interface NestedInteger 

/** @return true if this NestedInteger holds a single integer, rather than a nested list */ 
boolean isInteger(); 

/** @return the single integer that this NestedInteger holds, if it holds a single integer 
* Return null if this NestedInteger holds a nested list */ 
Integer getInteger(); 

/** @return the nested list that this NestedInteger holds, if it holds a nested list 
* Return null if this NestedInteger holds a single integer */ 
List<NestedInteger> getList(); 
}

A Linkedin interview question. The original problem can be found on Careercup.

Just use recursion. Return the integer * level if the NestedInteger is a single integer, otherwise recursively check all the lists in the NestedInteger.

Apparently the warning that I "should not implement it, or speculate about its implementation" is correct. Yet I am still curious...



public class SumofNestedIntegers {
 public int depthSum(List input) {
  if (input == null)
   return 0;
  return getSum(input, 1);
 }
 private int getSum(List  input, int depth) {
   int sum = 0;
   for (NestedInteger nested : input) {
    if (nested.isInteger()) {
     sum += nested.getInteger() * depth;
    }
    else {
     sum += getSum(nested.getList(), depth++);
    } 
  }
   return sum;
 }
}

Wednesday, December 17, 2014

Flatten Binary Tree to Linked List

A very beautiful tree traversal problem. No doubt recursion will be the solution.
Track the last node visited, and make the current node as the right child of the last node. Recursively go down to the left, then go to the right.


  public class TreeNode {
      int val;
      TreeNode left;
      TreeNode right;
      TreeNode(int x) { val = x; }
  }
 
public class FlattenTree {
    private TreeNode lastNode = null;
    public void flatten(TreeNode root) {
        if (root == null)
            return;
        if (lastNode != null)
        {
            lastNode.left = null;
            lastNode.right = root;
        }
        lastNode = root;
        TreeNode right = root.right;
        flatten(root.left);
        flatten(right);
            
        
    }
}

Sunday, December 14, 2014

Regular Expression Matching

Implement regular expression matching with support for '.' and '*'.
'.' Matches any single character.
'*' Matches zero or more of the preceding element.

The matching should cover the entire input string (not partial).

The function prototype should be:
bool isMatch(const char *s, const char *p)

Some examples:
isMatch("aa","a") → false
isMatch("aa","aa") → true
isMatch("aaa","aa") → false
isMatch("aa", "a*") → true
isMatch("aa", ".*") → true
isMatch("ab", ".*") → true
isMatch("aab", "c*a*b") → true

I took a lot of figuring out this problem because at first I don't really understand what regular expression (regex) means.

It is very clear that '.' only matches one single character. However, when it comes to '*', the explanation that of 'zero or more of the preceding element' is ambiguous. It turns out that there must be one character before *, but the character doesn't have to be matched with any character is the original character.
This explains that "aab" - "c*a*b" is a match.

The logic behind this problem is not very hard.

1. If p is an empty string, return if s is an empty string (the null condition as well)
2. If  the second character in p is not '*', if the first characters in both strings match, then we compare the substrings (recursively), otherwise return false.
3.  If the second character in p is '*', then the first two characters in p is matched. So we continue from the third character (p.substring(2)).

Update: 2015-01-02
1. In the case that s = "" and p = "a*", they still match. So s.length() doesn't mean anything.
2. The case when p.length() == 1 and p.charAt(1) != '*' can be combined together for cleaner code. For that condition, if s.length() is less than 1, we are sure that it's false. Otherwise, if the first characters in s and p don't match, we can return false too. Then we move on to the next character.

Update: 2015 - 01 - 15
Walk through:
1. check null conditions;
2. if p.length() == 0, return s.length() == 0
3. if p.length() == 1 or p.charAt(1) != '*', check:
    1. if s.length() < 1, or s.charAt(0) doesn't match p.charAt(0) or p.charAt(0) is not '.', return false;
    2. otherwise recursively check s.substring(1) and p.substring(1)
4. if p.charAt(1) == '*'. Assuming at first that the first character in p ("x*") doesn't match anything in s, so compare s with p.substring(2), if doesn't match, check if the first character in s and p  match, or if the first character in p is '.', if one of the conditions satisfy, increment index_s and check s.substring(index_s + 1).


public class Solution {
    public boolean isMatch(String s, String p) {
        if (p == null || s == null)
            return false;
        if (p.length() == 0)
            return s.length() == 0;
        if (p.equals(s))
            return true;
        
        
        if (p.length() == 1 ||  p.charAt(1) != '*')
        {
            if (s.length() < 1 || (p.charAt(0) != s.charAt(0) && p.charAt(0) != '.'))
                return false;
            return isMatch(s.substring(1), p.substring(1));
        }
        //if the first characters don't match, we need to compare substring_p with the whole s
        //e.g., s = "aab", p = "c*a*b" index_s + 1 = 0
        int index_s = -1;
        while (index_s < s.length() &&(index_s < 0 || s.charAt(index_s) == p.charAt(0) || p.charAt(0) == '.'))
        {
           // the first character is matched by '*', we move on to the next character
            if (isMatch(s.substring(index_s + 1), p.substring(2)))
                return true;
            index_s++;
        }
        return false;
    }
}

Saturday, December 13, 2014

Unique Binary Search Tree I and II

A very interesting problem. At first glance, I had no idea how to approach it. Thanks to Stackoverflow (again), for helping me solve the problem.

According to Binary Search Tree's definition, in order for node i to be the root, it's left subtree can only be generated from node 0 to i - 1, and it's right subtree can only be generated from i + 1 to n.

So, Tree[n] = Tree[0] * Tree[n - 1] + Tree[1] * Tree[n - 2] + ... + Tree[i] * Tree[n - i - 1] + ... + Tree[n - 1] * Tree[0]


public class UniqueBST {
    public int numTrees(int n) {
        if (n < 0)
            return 0;
        if (n == 0 || n == 1)
            return 1;
        int[] Tree = new int[n + 1];
        Tree[0] = 1;
        Tree[1] = 1;
        
        for (int i = 2; i <= n; i++)
        {
            //j represents the left subtree
            for (int j = 0; j < i; j++)
                Tree[i] += Tree[j] * Tree[i - j - 1];
        }
        return Tree[n];
        
    }
}

The second problem is derived from the same idea. The only difference is, now we need to use recursion to generate every left and right subtree.



public class Solution {
    public ArrayList generateTrees(int n) {
        return generateTreeHelper(1, n);
    }
    private ArrayList generateTreeHelper(int start, int end)
    {
        ArrayList rst = new ArrayList();
        //reach to the leaf
        if (start > end)
        {
            rst.add(null);
            return rst;
        }
        for (int i = start; i <= end; i++)
        {
            ArrayList left = generateTreeHelper(start, i - 1);
            ArrayList right = generateTreeHelper(i + 1, end);
            for (TreeNode l : left)
            {
                for (TreeNode r : right)
                {
                    TreeNode root = new TreeNode(i);
                    root.left = l;
                    root.right = r;
                    rst.add(root);
                }
            }
            
        }
        return rst;
    }
}

Word Break ... ||

When you have one, you must have two! Instead, this one uses a recursion. HashMap is always an amazing data structure. This one uses the map to store temporary strings and corresponding arrays, and thus reduces number of recursions.

Given a string s and a dictionary of words dict, add spaces in s to construct a sentence where each word is a valid dictionary word.
Return all such possible sentences.
For example, given
s = "catsanddog",
dict = ["cat", "cats", "and", "sand", "dog"].
A solution is ["cats and dog", "cat sand dog"].

Take the "catsanddog" as the example.
When the iteration detects "cat", it splits the string to prefix ="cat" and suffix = "sanddog". Take the suffix as the input, the method checks for the next prefix ("sand"). When it detects "dog", the input is in the dictionary, so we simply add the input into the result array (rst) and return.

"catsanddog" -> len == 3, "cat" + "sanddog" -> "sand" + "dog" -> "dog", add to the map and rst, return rst -> "sand" + " " +  "dog" (from tmp), add to the map and rst, return rst -> "cat" + " " + "sand dog" = "cat sand dog", add to the map and rst;
"catsanddog" -> len == 4, "cats" + "anddog" -> "and" + "dog" -> "dog", get from map, return rst -> "and" + " " + "dog" -> "cats" + " " + "and dog" = "cats and dog", add to the map and rst, return rst;
                    



public class Solution {
    public ArrayList wordBreak(String s, Set dict) {
        ArrayList rst = new ArrayList ();
        if (s == null || dict.isEmpty())
            return rst;
        HashMap> map = new HashMap>();
        rst = wordBreakHelper(s, dict, map);
        return rst;
        
    }
    private ArrayList wordBreakHelper(String s, Set dict, HashMap> map)
    {
        if (map.containsKey(s))
            return map.get(s);
        ArrayList rst = new ArrayList();
        int length = s.length();
        if (length <= 0)
            return rst;
        for (int len = 1; len <= length; len++)
        {
            String prefix = s.substring(0, len);
            if (dict.contains(prefix))
            {
                if (len == length)
                    rst.add(prefix);
                else
                {
                    String suffix = s.substring(len);
                    ArrayList tmp = wordBreakHelper(suffix, dict, map);
                    for (String items : tmp)
                    {
                        String words = prefix + " " + items;
                        rst.add(words);
                    }
                }
            }
        }
        map.put(s, rst);
        return rst;
    }
}