Question

Formatted question description: https://leetcode.ca/all/107.html

107	Binary Tree Level Order Traversal II

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]
]

@tag-tree

Algorithm

The traversal from the bottom sequence is actually traversal from the top, but the final storage method has changed.

Code

Java

import java.util.*;

public class Binary_Tree_Level_Order_Traversal_II {

	/**
	 * Definition for a binary tree node.
	 * public class TreeNode {
	 *     int val;
	 *     TreeNode left;
	 *     TreeNode right;
	 *     TreeNode(int x) { val = x; }
	 * }
	 */
	public class Solution {
	    public List<List<Integer>> levelOrderBottom(TreeNode root) {

	    	List<List<Integer>> list = new ArrayList<List<Integer>>();

	    	if (root == null) {
	    		return list;
	    	}

	    	Queue<TreeNode> sk = new LinkedList<>();

	    	sk.offer(root);
	    	sk.offer(null);// @note: use null as marker for end of level

	    	List<Integer> oneLevel = new ArrayList<>();
	    	while (!sk.isEmpty()) {

	    		TreeNode current = sk.poll();

	    		if (current == null) {
	    			List<Integer> copy = new ArrayList<>(oneLevel);
	    			list.add(0, copy); // diff of I and II: insert to head

	    			// clean after one level recorded
	    			oneLevel.clear();// @memorize: this api

	    			// @note:@memorize: if stack is now empty then DO NOT add null, or else infinite looping
	    			// sk.offer(null); // add marker
	    			if (!sk.isEmpty()) {
	    				sk.offer(null); // add marker
	    			}

	    			continue;
	    		}

	    		oneLevel.add(current.val);

	    		// @note:@memorize: since using null as marker, then must avoid adding null when children are null
	    		// sk.offer(current.left);
	    		// sk.offer(current.right);
	    		if (current.left != null) {
	    			sk.offer(current.left);
	    		}
	    		if (current.right != null) {
	    			sk.offer(current.right);
	    		}

	    	}

	    	return list;
	    }
	}

	public class Solution_dummyNodeAsMarker {
	    public  List<List<Integer>> levelOrderBottom(TreeNode root) {

	        LinkedList<List<Integer>> result = new LinkedList<List<Integer>>();

	        if(root == null) {
	        	return result;
			}

			// Array deques have no capacity restrictions, they grow as necessary
			Queue<TreeNode> queue = new ArrayDeque<TreeNode>(); // @note: another implementation
	        queue.add(root);
	        TreeNode dummy = new TreeNode(0);

	        queue.add(dummy);

	        List<Integer> currentLevel = new ArrayList<Integer>();
	        while(queue.size() > 1){
	        	TreeNode current = queue.poll();

	        	if (current.hashCode() != dummy.hashCode()) { // more specific with hashCode()
	        		currentLevel.add(current.val);
	        		if(current.left != null) queue.add(current.left);
	            	if(current.right != null) queue.add(current.right);
	        	} else {
	        		result.addFirst(new ArrayList<Integer>(currentLevel));
	        		currentLevel.clear();
	        		queue.add(dummy);
	        	}
	        }

	        // @note: LinkedList has API addFirst()
	        result.addFirst(currentLevel);

	        // or call reverse()
			// Collections.reverse(result);

	        return result;
	    }
	}

}

All Problems

All Solutions