Some discussion about the hot “invert a binary tree”

This classical interview algorithm problem has been widely discussed due to this: Google: 90% of our engineers use the software you wrote (Homebrew), but you can’t invert a binary tree on a whiteboard so fuck off.(this original tweet). It may implies that even the best programmer needs to practice the algorithms again and again(also may implies other interesting cases but we are not going to talk about it here.)

Actually it is not a very complex problem. It will implement a pre order traverse because if you insert a sequence of nodes in pre order it would give you the original tree. Firstly you should check the null condition, and then exchange the left child and right child of the current root node, then recursively call the function by passing the left child and the right child as the parameter.

I got three solutions of this problems. The first one is on the stackoverflow:

void ReverseTree(Node root){
    Node tmp = root.Left;
         root.Left = root.Right;
         root.Right = tmp;

    if(root.Left != null) ReverseTree(root.Left);
    if(root.Right != null) ReverseTree(root.Right);
}
  
and the second solution is my solution on the leetcode:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/

public class Solution {

public Node invertTree(Node root) {

        if(root == null)

            return null;

        else{

            Node newRoot = new Node(root.key);

            invertTree(newRoot,root);

            return newRoot;

        }

    }

 

private void invertTree(Node newRoot,Node root){

        if(root == null){newRoot = null;}

        else{

            if(root.left != null)

            newRoot.right =new Node(root.left.key);

            invertTree(newRoot.right,root.left);

            if(root.right != null)

            newRoot.left = new Node(root.right.key);

            invertTree(newRoot.left,root.right);

        }

    }

}

 

This solution implements a  private auxiliary function, and returns a new inverted root node and doesn’t change the original one. The biggest difference between them is that on the second solution, you need to create a new newRoot instance to assign to the newRoot’s children node, not the root’s child node. The reason is that when you write this:

newRoot.left = root.right;

you will bind these two references newRoot.right and root.left together. Remember in Java once you use “=” to bind two references together, they would be the alias of one object and can never be separated. So when you go into the recursion call and do the step “newRoot.left.right = root.right.left”, actually root.left.right also be changed to the root.right.left. So you may have the following case: 

Input:[4,2,7,1,3,6,9](pre order)
Output:[4,7,2,6,6,1,1]
Expected:[4,7,2,9,6,3,1]
 
The first solution doesn’t need to consider about it because it exchange the original root’s left child and right child.
(another version of the solution 1 that returns the root node to match the leetcode’s requirement: )
public Node ReverseTree(Node root){
    if(root == null)
      return null;
    Node tmp = root.Left;
         root.Left = root.Right;
         root.Right = tmp;

    if(root.Left != null) root.left = ReverseTree(root.Left);
    if(root.Right != null) root.right = ReverseTree(root.Right);
}

 

the third solution:
    I got this solution on the quora. This is a pretty interesting solution. The question likes this:
Given: 1
/ \
2 3
\
4
output:   4
/
2 3
\ /
1
It seems that the asker has different understanding about the “invert”.
The solution is the following:
 
public TreeNode invertTree(TreeNode root){
if (root==null) return null; // line 1if (root.left != null){ // line 2
TreeNode leftchild = invertTree(root.left); // line 3
leftchild .right=root; // line 4
}
 

if (root.right != null){ // line 5
TreeNode rightchild = invertTree(root.right); // line 6
rightchild.left=root; // line 7
}

root.left=null; // line 8
root.right=null; // line 9

return root; // line 10
}

 

it implements the post order traverse to get the “inverted tree “. There is only problem on is solution: it’s dead. One can only get the reference it points to, not it is pointed. So when you run this code, you will only get the root node and all its children are diminished by the java garbage collection.
 
the stackoverflow’s solution: http://stackoverflow.com/questions/9460255/reverse-a-binary-tree-left-to-right
the leetcode’s question: https://leetcode.com/problems/invert-binary-tree/
the quora’s solution: http://www.quora.com/What-is-the-algorithmic-approach-to-invert-a-given-binary-tree
posted @ 2015-06-19 10:15  SeanYuan  阅读(183)  评论(0编辑  收藏  举报