Wednesday, August 15, 2012

Longest Palindromic Substring


Easy but invalid solution:

Reverse S and become S’.
This seemed to work, let’s see some examples below.
For example,
S = “caba”, S’ = “abac”.
The longest common substring between S and S’ is “aba”, which is the answer.
Let’s try another example:
S = “abacdfgdcaba”, S’ = “abacdgfdcaba”.
The longest common substring between S and S’ is “abacd”. Clearly, this is not a valid palindrome.

We could see that the longest common substring method fails when there exists a reversed copy of a non-palindromic substring in some other part of S. To rectify this, each time we find a longest common substring candidate, we check if the substring’s indices are the same as the reversed substring’s original indices. If it is, then we attempt to update the longest palindrome found so far; if not, we skip this and find the next candidate.
This gives us a O(N2) DP solution which uses O(N2) space.

Print Edge Nodes (Boundary) of a Binary Tree

    _30_
   /    \
  10    20
 /     /  \
50    45  35

The correct solution should print 30, 10, 50, 45, 35, 20.

        ______30______
       /              \
    __20__          __40__
   /      \        /      \
  10      25      35      50
 /  \       \            /
 5  15      28          41

The correct solution should print 30, 20, 10, 5, 15, 28, 35, 41, 50, 40.

   _______________28_______________
  /                                \
  4____                        ____69
       \                      /
      __8__                __56__
     /     \              /      \
   __7     12__        __34    __27__
  /            \      /       /      \
  5_          _13    _2      _3      39
    \        /      /       /
     6      11     10       9

correct output of: 28, 4, 8, 7, 5, 6, 11, 10, 9, 39, 27, 56, 69.
Hint:
To solve this problem, you first need to pay attention to these three key areas:
  • Printing the leftmost edges from top to bottom. When a node is a leftmost edge, its left child must also be a leftmost edge.
  • Printing the leaves from left to right. Remember depth-first traversal?
  • Printing the rightmost edges. You would need to print from bottom to top. The key is printing in the opposite order. Easy if you know how to manipulate recursion into a stack-based solution. Remember post-order traversal?
Solution:
We could divide the tree into two subtrees. One is the left subtree, and the other is the right subtree.

For the left subtree, we print the leftmost edges from top to bottom. Then we print its leaves from left to right.

For the right subtree, we print its leaves from left to right, then its rightmost edges from bottom to top.
Printing the leaves from left to right order is a classic example of depth-first traversal. How do you know if a node is a leaf? Easy, if the node does not have both left and right children.

Printing the leftmost edges is just a trivial addition to the depth-first traversal. When a node is a leftmost edge, then its left child must also be a leftmost edge. We could use a variable to pass this information down the tree. Please note that you must add the condition to avoid printing the node twice (a node could be a leftmost edge as well as a leaf node).

Printing the rightmost edges from bottom to top is easy if you realize the trick of manipulating recursion as a stack. Try relate this with how post-order traversal works. When calling recursive functions, function calls are pushed onto a stack, and therefore you could use the implicit stack to your advantage. This trick is especially handy when applied in situation where you need to reverse the order of operations.


#include<stdio.h>
#include<stdlib.h>

struct node {
    struct node *left;
    struct node *right;
    int data;
};

struct node *newnode(int data)
{
        struct node *node=(struct node *)malloc(sizeof(struct node));
        node->data=data;
        node->left=NULL;
        node->right=NULL;
        return node;
}

void printLeftBoundary(node *root) {

    if(root==NULL) return;
    if(root->left) {
       printf("%d ",root->data);
       printLeftBoundary(root->left);
    }
    else if(root->right) {
       printf("%d ",root->data);
       printLeftBoundary(root->right);
    }
}

void printLeafBoundary(node *root) {

    if(root) {
   
       printLeafBoundary(root->left);
      
       if(root->left==NULL && root->right==NULL)
          printf("%d ",root->data);
         
       printLeafBoundary(root->right);
    }
}

void printRightBoundary(node *root)
{
    if(root==NULL) return;
    if(root->right) {
       printRightBoundary(root->right);
       printf("%d ",root->data);
    }
    else if(root->left) {
       printRightBoundary(root->left);
       printf("%d ",root->data);
    }
}

void printBoundary(node *root)
{
if(root)
    {
        printf("%d ", root->data);
       
        printLeftBoundary(root->left);
       
        printLeafBoundary(root);
       
        printRightBoundary(root->right);
    }
}

int main()
{
    struct node *root=newnode(1000);
    root->left=newnode(500);
    root->right=newnode(1500);
    root->left->right=newnode(510);
    root->left->right->right=newnode(600);   
    root->left->left=newnode(240);
    root->left->left->left=newnode(120);
    root->left->left->right=newnode(300);   
    root->right->left=newnode(1300);
    root->right->left->right=newnode(1320);   
   
    printBoundary(root);
   

    return 0;
}
Time Complexity PrintLeftBoundary - O(h), where h is height of tree, log(n) nodes on left are visited once PrintLeafBoundary - O(n), as each node is visited once PrintRightBoundary - O(h), where h is height of tree, log(n) nodes on right are visited once. O(n+2h) total time complexity

Lowest Common Ancestor of a Binary Search Tree (BST)

        _______6______
       /              \
    ___2__          ___8__
   /      \        /      \
   0      _4       7       9
         /  \
         3   5

Using the above tree as an example, the lowest common ancestor (LCA) of nodes 2 and 8 is 6. LCA of nodes 2 and 4 is 2
Hint:
A top-down walk from the root of the tree is enough.

Solution:
There’s only three cases you need to consider.
  1. Both nodes are to the left of the tree.
  2. Both nodes are to the right of the tree.
  3. One node is on the left while the other is on the right.
For case 1), the LCA must be in its left subtree. Similar with case 2), LCA must be in its right subtree. For case 3), the current node must be the LCA.
Therefore, using a top-down approach, we traverse to the left/right subtree depends on the case of 1) or 2), until we reach case 3), which we concludes that we have found the LCA.
A careful reader might notice that we forgot to handle one extra case. What if the node itself is equal to one of the two nodes? This is the exact case from our earlier example! (The LCA of 2 and 4 should be 2). Therefore, we add another case number ):
4. When the current node equals to either of the two nodes, this node must be the LCA too.
The run time complexity is O(h), where h is the height of the BST. Translating this idea to code is straightforward (Note that we handle case 3) and 4) in the else statement to save us some extra typing

Node *LCA(Node *root, Node *p, Node *q) {
  if (!root || !p || !q) return NULL;
  if (max(p->data, q->data) < root->data)
    return LCA(root->left, p, q);
  else if (min(p->data, q->data) > root->data)
    return LCA(root->right, p, q);
  else
    return root;
}

Lowest Common Ancestor of a Binary Tree "WITHOUT" Parent pointers

        _______3______
       /              \
    ___5__          ___1__
   /      \        /      \
   6      _2       0       8
         /  \
         7   4

Using the tree above as an example, the LCA of nodes 5 and 1 is 3. Please note that LCA for nodes 5 and 4 is 5.
Hint:
Top-down or bottom-up? Consider both approaches and see which one is more efficient.

A Top-Down Approach (Worst case O(n2) ):
Let’s try the top-down approach where we traverse the nodes from the top to the bottom. First, if the current node is one of the two nodes, it must be the LCA of the two nodes. If not, we count the number of nodes that matches either p or q in the left subtree (which we call totalMatches). If totalMatches equals 1, then we know the right subtree will contain the other node. Therefore, the current node must be the LCA. If totalMatches equals 2, we know that both nodes are contained in the left subtree, so we traverse to its left child. Similar with the case where totalMatches equals 0 where we traverse to its right child.



// Return #nodes that matches P or Q in the subtree.
int countMatchesPQ(Node *root, Node *p, Node *q) {
  if (!root) return 0;
  int matches = countMatchesPQ(root->left, p, q) + countMatchesPQ(root->right, p, q);
  if (root == p || root == q)
    return 1 + matches;
  else
    return matches;
}

Node *LCA(Node *root, Node *p, Node *q) {
  if (!root || !p || !q) return NULL;
  if (root == p || root == q) return root;
  int totalMatches = countMatchesPQ(root->left, p, q);
  if (totalMatches == 1)
    return root;
  else if (totalMatches == 2)
    return LCA(root->left, p, q);
  else /* totalMatches == 0 */
    return LCA(root->right, p, q);
}
What is the run time complexity of this top-down approach?
First, just for fun, we assume that the tree contains n nodes and is balanced (with its height equals to log(n) ). In this case, the run time complexity would be O(n). Most people would guess a higher ordered complexity than O(n) due to the function countMatchesPQ() traverses the same nodes over and over again. Notice that the tree is balanced, you cut off half of the nodes you need to traverse in each recursive call of LCA() function. The proof that the complexity is indeed O(n) is left as an exercise to the reader.
What if the tree is not necessarily balanced? Then in the worst case the complexity could go up to O(n2). Why? Could you come up with such case? (Hint: The tree might be a degenerate tree).

A Bottom-up Approach (Worst case O(n) ):Using a bottom-up approach, we can improve over the top-down approach by avoiding traversing the same nodes over and over again.
We traverse from the bottom, and once we reach a node which matches one of the two nodes, we pass it up to its parent. The parent would then test its left and right subtree if each contain one of the two nodes. If yes, then the parent must be the LCA and we pass its parent up to the root. If not, we pass the lower node which contains either one of the two nodes (if the left or right subtree contains either p or q), or NULL (if both the left and right subtree does not contain either p or q) up.

Sounds complicated? Surprisingly the code appears to be much simpler than the top-down one.


Node *LCA(Node *root, Node *p, Node *q) {
  if (!root) return NULL;
  if (root == p || root == q) return root;
  Node *L = LCA(root->left, p, q);
  Node *R = LCA(root->right, p, q);
  if (L && R) return root;  // if p and q are on both sides
  return L ? L : R;  // either one of p,q is on one side OR p,q is not in L&R subtrees
}

Interview Websites

Maximum Height (Depth) of a Binary Tree

The maximum height of a binary tree is defined as the number of nodes along the path from the root node to the deepest leaf node. Note that the maximum height of an empty tree is 0.

Recursive Solution:
We can solve this easily using recursion. Why? Because each of the leftChild and rightChild of a node is a sub-tree itself. We first compute the max height of left sub-tree, then compute the max height of right sub-tree. Therefore, the max height of the current node is the greater of the two max heights + 1. For the base case, the current node is NULL, we return zero. NULL signifies there is no tree, therefore its max height is zero.

int maxHeight(BinaryTree *p)
{
     if (!p) return 0;

     int left_height = maxHeight(p->left);
     int right_height = maxHeight(p->right);

     return (left_height > right_height) ? left_height + 1 : right_height + 1;
}

Pop in Linked List

Extract the data from the head node, delete the node, advance the head pointer to point at the next node in line. Uses a reference parameter since it changes the head pointer.

int Pop(struct node** headRef) 
{
    struct node* head;
    int result;
    head = *headRef;
    
    assert(head != NULL);
    
    result = head->data; // pull out the data before the node is deleted
    *headRef = head->next; // unlink the head node for the caller
    
    // Note the * -- uses a reference-pointer
    //  just like Push() and DeleteList().
    
    free(head); // free the head node
    return(result); // don't forget to return the data from the link
}

Delete Linked List

Delete the whole list and set the head pointer to NULL. There is a slight complication
inside the loop, since we need extract the .next pointer before we delete the node, since
after the delete it will be technically unavailable.

void DeleteList(struct node** headRef)
{
    struct node* current = *headRef; // deref headRef to get the real head
    struct node* next;

    while (current != NULL)
    {
        next = current->next; // note the next pointer
        free(current); // delete the node
        current = next; // advance to the next node
    }

    *headRef = NULL; // Again, deref headRef to affect the real head back in the caller.
}

GetNth() in a Linked List


int GetNth(struct node* head, int index)
{
    struct node* current = head;
    int count = 0; // the index of the node we're currently looking at
    while (current != NULL)
    {
        if (count == index) return(current->data);
        count++;
        current = current->next;
    }

    assert(0); // if we get to this line, the caller was asking
    // for a non-existent element so we assert fail.
}

Count number of times a value repeated in Linked List


int Count(struct node* head, int searchFor)
{
    struct node* current = head;
    int count = 0;
    while (current != NULL)
    {
        if (current->data == searchFor) count++;
        current = current->next;
    }
    return count;
}

Length of Linked List


// Return the number of nodes in a list (while-loop version)
int Length(struct node* head)
{
    int count = 0;
    struct node* current = head;
    while (current != NULL)
    {
        count++;
        current = current->next;
    }
    return(count);
}

Insert in a BST

Insert()
Insert() -- given a binary search tree and a number, insert a new node with the given number into the tree in the correct place. The insert() code is similar to lookup(), but with the complication that it modifies the tree structure. As described above, insert() returns the new tree pointer to use to its caller. Calling insert() with the number 5 on this tree...
2
/ \
1 10
returns the tree...
2
/ \
1 10
/
5
The solution shown here introduces a newNode() helper function that builds a single node. The base-case/recursion structure is similar to the structure in lookup() -- each call checks for the NULL case, looks at the node at hand, and then recurs down the left or right subtree if needed.

/*
 Helper function that allocates a new node
 with the given data and NULL left and right
 pointers.
*/
struct node* NewNode(int data) {
  struct node* node = new(struct node);    // "new" is like "malloc"
  node->data = data;
  node->left = NULL;
  node->right = NULL;

  return(node);
} 

/*
 Give a binary search tree and a number, inserts a new node
 with the given number in the correct place in the tree.
 Returns the new root pointer which the caller should
 then use (the standard trick to avoid using reference
 parameters).
*/
struct node* insert(struct node* node, int data) {
  // 1. If the tree is empty, return a new, single node
  if (node == NULL) {
    return(newNode(data));
  }
  else {
    // 2. Otherwise, recur down the tree
    if (data <= node->data) node->left = insert(node->left, data);
    else node->right = insert(node->right, data);

    return(node); // return the (unchanged) node pointer
  }
}

Check whether two trees are structurally identical


/*
 Given two trees, return true if they are
 structurally identical.
*/
int sameTree(struct node* a, struct node* b) {
  // 1. both empty -> true
  if (a==NULL && b==NULL) return(true);
  // 2. both non-empty -> compare them
  else if (a!=NULL && b!=NULL) {
    return(
      a->data == b->data &&
      sameTree(a->left, b->left) &&
      sameTree(a->right, b->right)
    );
  }
  // 3. one empty, one not -> false
  else return(false);
}

Check whether a given tree is a BST


/*
 Returns true if a binary tree is a binary search tree.
*/
int isBST(struct node* node) {
  if (node==NULL) return(true);
  // false if the max of the left is > than us

  // (bug -- an earlier version had min/max backwards here)
  if (node->left!=NULL && maxValue(node->left) > node->data)
    return(false);

  // false if the min of the right is <= than us
  if (node->right!=NULL && minValue(node->right) <= node->data)
    return(false);

  // false if, recursively, the left or right is not a BST
  if (!isBST(node->left) || !isBST(node->right))
    return(false);

  // passing all that, it's a BST
  return(true);
} 
OR

/*
 Returns true if the given tree is a binary search tree
 (efficient version).
*/
int isBST2(struct node* node) {
  return(isBSTUtil(node, INT_MIN, INT_MAX));
}
/*
 Returns true if the given tree is a BST and its
 values are >= min and <= max.
*/
int isBSTUtil(struct node* node, int min, int max) {
  if (node==NULL) return(true);

  // false if this node violates the min/max constraint
  if (node->data<min || node->data>max) return(false);

  // otherwise check the subtrees recursively,
  // tightening the min or max constraint
  return
    isBSTUtil(node->left, min, node->data) &&
    isBSTUtil(node->right, node->data+1, max)
  );
}

Create a new duplicate node for each node in a BST

/*
 For each node in a binary search tree,
 create a new duplicate node, and insert
 the duplicate as the left child of the original node.
 The resulting tree should still be a binary search tree.
 So the tree...
    2
   / \
  1   3

 Is changed to...
       2
      / \
     2   3
    /   /
   1   3
  /
 1

*/

void doubleTree(struct node* node) {
  struct node* oldLeft;

  if (node==NULL) return;

  // do the subtrees
  doubleTree(node->left);
  doubleTree(node->right);

  // duplicate this node to its left
  oldLeft = node->left;
  node->left = newNode(node->data);
  node->left->left = oldLeft;
}

Mirror a BST

/*
 Change a tree so that the roles of the
 left and right pointers are swapped at every node.
 So the tree...
       4
      / \
     2   5
    / \
   1   3

 is changed to...
       4
      / \
     5   2
        / \
       3   1
*/

void mirror(struct node* node) {
  if (node==NULL) {
    return;
  }
  else {
    struct node* temp;

    // do the subtrees
    mirror(node->left);
    mirror(node->right);

    // swap the pointers in this node
    temp = node->left;
    node->left = node->right;
    node->right = temp;
  }
}

Print out all root-to-leaf paths


/*
 Given a binary tree, print out all of its root-to-leaf
 paths, one per line. Uses a recursive helper to do the work.
*/
void printPaths(struct node* node) {
  int path[1000];
  printPathsRecur(node, path, 0);
}

/*
 Recursive helper function -- given a node, and an array containing
 the path from the root node up to but not including this node,
 print out all the root-leaf paths.
*/
void printPathsRecur(struct node* node, int path[], int pathLen) {
  if (node==NULL) return;

  // append this node to the path array
  path[pathLen] = node->data;
  pathLen++;

  // it's a leaf, so print the path that led to here
  if (node->left==NULL && node->right==NULL) {
    printArray(path, pathLen);
  }
  else {
  // otherwise try both subtrees
    printPathsRecur(node->left, path, pathLen);
    printPathsRecur(node->right, path, pathLen);
  }
}

// Utility that prints out an array on a line.
void printArray(int ints[], int len) {
  int i;
  for (i=0; i<len; i++) {
    printf("%d ", ints[i]);
  }
  printf("\n");
}

Find path from root to leaf with a given sum


/*
 Given a tree and a sum, return true if there is a path from the root
 down to a leaf, such that adding up all the values along the path
 equals the given sum.
 Strategy: subtract the node value from the sum when recurring down,
 and check to see if the sum is 0 when you run out of tree.
*/
int hasPathSum(struct node* node, int sum) {
  // return true if we run out of tree and sum==0
  if (node == NULL) {
    return(sum == 0);
  }
  else {
  // otherwise check both subtrees
    int subSum = sum - node->data;
    return(hasPathSum(node->left, subSum) ||
           hasPathSum(node->right, subSum));
  }
}

Print BST "Postorder"


[sourcecode]
/*
 Given a binary tree, print its
 nodes according to the "bottom-up"
 postorder traversal.
*/
void printPostorder(struct node* node) {
  if (node == NULL) return;
  // first recur on both subtrees
  printTree(node->left);
  printTree(node->right);

  // then deal with the node
  printf("%d ", node->data);
}
[/sourcecode]

Print BST "Inorder"


[sourcecode]
/*
 Given a binary search tree, print out
 its data elements in increasing
 sorted order.
*/
void printTree(struct node* node) {
  if (node == NULL) return;
  printTree(node->left);
  printf("%d ", node->data);
  printTree(node->right);
}
[/sourcecode]

minValue() of BST


[sourcecode]
/*
 Given a non-empty binary search tree,
 return the minimum data value found in that tree.
 Note that the entire tree does not need to be searched.
*/
int minValue(struct node* node) {
  struct node* current = node;
  // loop down to find the leftmost leaf
  while (current->left != NULL) {
    current = current->left;
  }

  return(current->data);
}
[/sourcecode]

maxDepth() of BST


The maximum height of a binary tree is defined as the number of nodes along the path from the root node to the deepest leaf node. Note that the maximum height of an empty tree is 0.
Recursive Solution:
We can solve this easily using recursion. Why? Because each of the leftChild and rightChild of a node is a sub-tree itself. We first compute the max height of left sub-tree, then compute the max height of right sub-tree. Therefore, the max height of the current node is the greater of the two max heights + 1. For the base case, the current node is NULL, we return zero. NULL signifies there is no tree, therefore its max height is zero.
[sourcecode]
/*
 Compute the "maxDepth" of a tree -- the number of nodes along
 the longest path from the root node down to the farthest leaf node.
*/
int maxDepth(struct node* node) {
  if (node==NULL) {
    return(0);
  }
  else {
    // compute the depth of each subtree
    int lDepth = maxDepth(node->left);
    int rDepth = maxDepth(node->right);
    // use the larger one
    if (lDepth > rDepth) return(lDepth+1);
    else return(rDepth+1);
  }
} 

[/sourcecode]

Tuesday, August 14, 2012

SQL Joins

The "Persons" table:
P_Id LastName FirstName Address         City
1 Hansen     Ola        Timoteivn 10  Sandnes
2 Svendson   Tove       Borgvn 23     Sandnes
3 Pettersen  Kari       Storgt 20     Stavanger
The "Orders" table:
O_Id OrderNo P_Id
1 77895 3
2 44678 3
3 22456 1
4 24562 1
5 34764 15

INNER JOIN
"List all the persons with any orders"

SELECT Persons.LastName, Persons.FirstName, Orders.OrderNo
FROM Persons
INNER JOIN Orders
ON Persons.P_Id=Orders.P_Id
ORDER BY Persons.LastName

The result-set will look like this:
LastName FirstName OrderNo
Hansen     Ola     22456
Hansen     Ola     24562
Pettersen  Kari    77895
Pettersen  Kari    44678

LEFT JOIN / LEFT OUTER JOIN
The LEFT JOIN keyword returns all the rows from the left table (table_name1), even if there are no matches in the right table (table_name2)

"List all the persons and their orders - if any"

SELECT Persons.LastName, Persons.FirstName, Orders.OrderNo
FROM Persons
LEFT JOIN Orders
ON Persons.P_Id=Orders.P_Id
ORDER BY Persons.LastName

The result-set will look like this:

LastName FirstName OrderNo
Hansen     Ola     22456
Hansen     Ola     24562
Pettersen  Kari    77895
Pettersen  Kari    44678
Svendson Tove      (null)

The LEFT JOIN keyword returns all the rows from the left table (Persons), even if there are no matches in the right table (Orders).

RIGHT JOIN / RIGHT OUTER JOIN
The RIGHT JOIN keyword returns all the rows from the right table (table_name2), even if there are no matches in the left table (table_name1)

"List all the orders with containing persons - if any"

SELECT Persons.LastName, Persons.FirstName, Orders.OrderNo
FROM Persons
RIGHT JOIN Orders
ON Persons.P_Id=Orders.P_Id
ORDER BY Persons.LastName


The result-set will look like this:
LastName FirstName OrderNo
Hansen     Ola     22456
Hansen     Ola     24562
Pettersen  Kari    77895
Pettersen  Kari    44678
(null)    (null)   34764

The RIGHT JOIN keyword returns all the rows from the right table (Orders), even if there are no matches in the left table (Persons).

Print all permutations of a string


permute("123", 0, 3);

function permute($str, $start, $strLength) {
  if ($start === $strLength) {
    var_dump($str);
    return;
  }
  for ($i=$start; $i<$strLength; $i++) {
    swap($str, $i, $start);
    permute($str, $start+1, $strLength);
    swap($str, $start, $i);
  }
}
 
function swap(&$str, $pos1, $pos2) { 
  $tmp = $str[$pos1]; 
  $str[$pos1] = $str[$pos2]; 
  $str[$pos2] = $tmp; 
}

Print all possible combinations of strings that can be made using a keypad given a number


telKeys("2133004655", "2133004655", 0, 10);

$keypad = array("ABC", "DEF", "GHI", "JKL", "MNO", "PQR", "STU", "VWX", "YZ");
function telKeys($original, $new, $start, $strLength) {
  global $keypad;
  if ($start === $strLength) {
    var_dump($new);
    return;
  }

    $new[$start] = $keypad[$original[$start]][0];
    telKeys($original, $new, $start+1, $strLength);
    
    $new[$start] = $keypad[($original[$start])][1];
    telKeys($original, $new, $start+1, $strLength);
    
    if(($original[$start]) < 8) {
        $new[$start] = $keypad[($original[$start])][2];
        telKeys($original, $new, $start+1, $strLength);
    }
}

Print given string in all combinations of uppercase and lowercasecharacters

Given a string we need to print the string with all possible combinations of the uppercase and lowercase characters in the string.
So given a string "abc", we need to print the following:
ABC
ABc
AbC
Abc
aBC
aBc
abC
abc
Solution is a simple recursive approach where we call the function again and again once with a character in lower case and another time with the same character in upper case. The code is similar to what we would write for all permutations of a string.

lowerUpper("abc", 0, 3);

function lowerUpper($str, $start, $strLength) {
  if ($start === $strLength) {
    var_dump($str);
    return;
  }
    
  $str[$start] = strtoupper($str[$start]);
  lowerUpper($str, $start+1, $strLength);
    
  $str[$start] = strtolower($str[$start]);
  lowerUpper($str, $start+1, $strLength);
}

ACID properties

    Atomic
    • Any database Transaction is all or nothing
    • If one part of the transaction fails it all fails
    • An incomplete transaction cannot exist
    • eg: Order & Shipment - Mark order as complete & mark as shipped at the same time.
    Consistent
    • Any transaction will take the data from one consistent state to another
    • Only consistent data is allowed to be written
    Isolated
    • No transaction should be able to interfere with another transaction
    • The same field cannot be updated by two sources at the exact same time
    Durable
    • Once  a transaction is committed it will stay that way
    • Save it once, read it forever unless modified / deleted

Print each level's data in a Binary Tree in a separate line


[sourcecode]
    3
   /  \
  9   20
     /  \
    15    7

For example, the level order output of the tree above is:

3
9 20
15 7
[/sourcecode]
  1. Implemented using a "Queue".
  2. First we enter root in the queue.
  3. As root is the only node at its level, we enter a dummy node after it to signal end of level.
  4. Remove a node from queue,
  5. If it is a normal node, we enter all its children in the queue.
  6. If it is a dummy node, we enter another dummy node in the queue (this signals that we have encountered all nodes in previous level and entered their children in the queue, so this level ends here).
  7. As we need to print each level in new line, we enter a new line when we see a dummy node
[sourcecode]
void printLevel(Node* root)
{
    queue<Node*> q;
    Node *dummy = NULL;
    if(root == NULL)
        return;
    //Enter root in the queue
    else
    {
        q.push(root);
        q.push(dummy);
    }
    //If queue is empty then we are done.
    while(!q.empty())
    {
        Node* temp = q.front();
        q.pop();
        //If its a dummy node
        if(temp == NULL)
        {
            cout<<endl;
            q.push(dummy);
        }
        //Else enter node's children in the queue
        if(temp->left!=NULL)
            q.push(temp->left);
        if(temp->right!=NULL)
            q.push(temp->right);
        //Print out node's data.
        cout<<temp->data<<" ";
    }
}
[/sourcecode]

Closures

Classic "last value" problem, when function declared within loop ends up using last value of an incrementing variable:

for (var i = 0; i < 10; i++)
{
    document.getElementById('box' + i).onclick = function()
    {
        alert('You clicked on box #' + i);
    };
}
This assigns 10 functions as event handlers to corresponding elements.Our intention is to have different `i` values in each of the event handlers. But this is not at all what happens in reality.

If you look closer, it's easy to see what's really going on. Each of the functions assigned to `onclick` has access to `i` variable. Since `i` variable is bound to the entire enclosing scope—just like any other variable declared with `var` or as function declaration—each of the functions have access to the same `i` variable. Once this snippet is executed, `i` variable keeps its last value—the one that was set when loop ended.

So how do we fix it? By taking advantage of closures, of course. The solution is simple: scope each of the `i` values to the level of event handler. Let's see how this is done:

for (var i = 0; i < 10; i++)
{
    document.getElementById('box' + i).onclick = (function(index) {
        return function() {
            alert('You clicked on box #' + index);
        };
    })(i);
}

OR

function makeHandler(index) 
{
    return function() 
    {
        alert('You clicked on box #' + index);
    };
}
for (var i = 0; i < 10; i++) 
{
    document.getElementById('box' + i).onclick = makeHandler(i);
}

Print every word that is an anagram of another word in the dictionary


An anagram is any word that rearranges the letters of another word to form itself. For example, “act” and “cat” are anagrams of each other, as well as “admirer” and “married”.

Easy Solution
Compare each word against every other word in the dictionary, checking if they are anagrams of each other by sorting by character and testing for equality. This requires O(n^2) and is a working solution.

Efficient Solution
Example dictionary: {cat, dog, sad, act, cab, mat, god }
--- Sort each word only once, saving it into a temporary copy of the dictionary
Copy dictionary and sort by character: { act, dgo, ads, act, abc, amt, dgo }

Flow 1:
Use a Hashtable with hash(eachWord) as key & count as value, if count > 1 it means there is an anagram creation of the hashtable is n*mLogm (m is the average number of letters in a word and n is the total number of words in the dictionary)

Flow 2: 
We can take it one step further and gain real savings from sorting the temporary copy as well, which only costs O(n log n). It then allows you to find anagrams in O(n) time by going down the list and checking neighbors for equality. However, you’ll have to store the index into the original dictionary of the word as well since they’ll get rearranged.
Example dictionary: {cat, dog, sad, act, cab, mat, god }
Copy dictionary along with index and sort by character:
{ (act 0), (dgo 1), (ads 2), (act 3), (abc 4), (amt 5), (dgo 6) }
Sort dictionary: { (abc 4), (act 0), (act 3), (ads 2), (amt 5), (dgo 1), (dgo 6) }
Go through and find matching neighbors, extracting their indices and printing the corresponding word in the dictionary: 0, 3, 1, 6 -> cat act dog god

Lowest Common Ancestor of a Binary Tree "WITH" Parent pointers


[sourcecode]
          ___3______
       /              \
    ___5__          ___1__
   /      \        /      \
   6      _2       0       8
         /  \
         7   4

Using the tree above as an example, the LCA of nodes 5 and 1 is 3. Please note that LCA for nodes 5 and 4 is 5.

[/sourcecode]

An easy solution:
As we trace the two paths from both nodes up to the root, eventually it will merge into one single path. The LCA is the exact first intersection node where both paths merged into a single path. An easy solution is to use a hash table which records visited nodes as we trace both paths up to the root. Once we reached the first node which is already marked as visited, we immediately return that node as the LCA.
[sourcecode]
Node *LCA(Node *root, Node *p, Node *q)
{
    hash_set <Node *> visited;
    while (p || q)
    {
        if (p)
        {
            if (!visited.insert(p).second)
            return p; // insert p failed (p exists in the table)
            p = p->parent;
        }
        if (q)
        {
            if (!visited.insert(p).second)
            return q; // insert q failed (q exists in the table)
            q = q->parent;
        }
    }
    return NULL;
}
[/sourcecode]
The run time complexity of this approach is O(h), where h is the tree’s height. The space complexity is also O(h), since it can mark at most 2h nodes.
The best solution:
A little creativity is needed here. Since we have the parent pointer, we could easily get the distance (height) of both nodes from the root. Once we knew both heights, we could subtract from one another and get the height’s difference (dh). If you observe carefully from the previous solution, the node which is closer to the root is always dh steps ahead of the deeper node. We could eliminate the need of marking visited nodes altogether. Why?
The reason is simple, if we advance the deeper node dh steps above, both nodes would be at the same depth. Then, we advance both nodes one level at a time. They would then eventually intersect at one node, which is the LCA of both nodes. If not, one of the node would eventually reach NULL (root’s parent), which we conclude that both nodes are not in the same tree. However, that part of code shouldn’t be reached, since the problem statement assumed that both nodes are in the same tree.
[sourcecode]
int getHeight(Node *p) 
{
    int height = 0;
    while (p) 
    {
        height++;
        p = p->parent;
    }
    return height;
}

// As root->parent is NULL, we don't need to pass root in.
Node *LCA(Node *p, Node *q) 
{
    int h1 = getHeight(p);
    int h2 = getHeight(q);
    // swap both nodes in case p is deeper than q.
    if (h1 > h2) 
    {
        swap(h1, h2);
        swap(p, q);
    }
    // invariant: h1 <= h2.
    int dh = h2 - h1;
    for (int h = 0; h < dh; h++)
    q = q->parent;
    while (p && q) 
    {
        if (p == q) return p;
        p = p->parent;
        q = q->parent;
    }
    return NULL; // p and q are not in the same tree
}
[/sourcecode]