Very classic question and one of the hardest one I've met recently!!!
The solution is also very clever and impressive! If I can solve this problem during interview, I guess Google could be my next internship company without doubt!
Ok, here we go:
Given a binary tree, return the bottom-up level order traversal of its nodes' values. (ie, from left to right, level by level from leaf to root).
For example:
Given binary tree {3,9,20,#,#,15,7}
,
3 / \ 9 20 / \ 15 7
return its bottom-up level order traversal as:
[ [15,7], [9,20], [3] ]
-----------------------------------------------------------------------------Explanation----------------------------------------------------------------------------
The problem is quite simple actually. Given a binary tree, we want to output according to the level. Therefore, the return type is such data structure as List<List<Integer>> where the internal list contains the integers in certain level and external list contains inner lists from bottom to top.
1) My first attempt is to do BFS and use Stack<Integer> to store those elements by using preorder traversal BFS. But the problem is after we done BFS, we cannot tell how many elements in each level.
2) Then I can't stop thinking maybe we can recursively add elements to its corresponding list recognized by its level, which is also the "tag" of its list!
Then I wrote my code like this:
//This is attribute
private List<List<Integer>> list = new ArrayList<List<Integer>>();
//this is main entry anyway
public List<List<Integer>> levelOrderBottom(TreeNode root) {
int length = getTreeLength(root);
initList(length);
order(root, length - 1);
return list;
}
//Do remember init list firstly and put empty son-list in it. That's helpful
private void initList(int length){
for(int i = 0; i < length; i++){
List<Integer> aList = new ArrayList<Integer>();
list.add(aList);
}
}
//obtain the height of the tree, very clever!
private int getTreeLength(TreeNode root){
if(root == null) return 0;
if(root.left == null && root.right == null) return 1;
return Math.max(getTreeLength(root.left) + 1, getTreeLength(root.right) + 1);
}
//very clever. when recursively traverse, just "get" corresponding level's aList from list to add more element.
//Very easy to imagine and pretty accurate. Bravo!
private void order(TreeNode root, int level){
if(root == null) return;
list.get(level).add(root.val);
if(root.left != null){
order(root.left, level - 1);
}
if(root.right != null){
order(root.right, level -1);
}
}
Very straightforward and easy to understand. Bravo done!