package com.freetymekiyan.algorithms.level.medium; import com.freetymekiyan.algorithms.utils.Utils.TreeNode; import java.util.ArrayList; import java.util.List; /** * Given a binary tree, collect a tree's nodes as if you were doing this: Collect and remove all leaves, repeat until * the tree is empty. * <p> * Example: * Given binary tree * | 1 * | / \ * | 2 3 * | / \ * | 4 5 * Returns [4, 5, 3], [2], [1]. * <p> * Explanation: * 1. Removing the leaves [4, 5, 3] would result in this tree: * <p> * | 1 * | / * | 2 * 2. Now removing the leaf [2] would result in this tree: * <p> * | 1 * 3. Now removing the leaf [1] would result in the empty tree: * <p> * [] * Returns [4, 5, 3], [2], [1]. * <p> * Company Tags: LinkedIn * Tags: Tree, Depth-first Search */ public class FindLeavesOfBinaryTree { /** * Tree, DFS(Backtracking). * Make use of one property of tree node, its getHeight. * Height is the number of edges from the node to the deepest leaf. * So leaf node will have getHeight 0. * This problem is just aggregating all nodes with same getHeight into a list. */ public List<List<Integer>> findLeaves(TreeNode root) { List<List<Integer>> res = new ArrayList<>(); getHeight(root, res); return res; } /** * Return the getHeight of a node. * Recurrence relation: * getHeight(node) = 1 + max(getHeight(node.left), getHeight(node.right)) * Base case: * If node is null, it's getHeight is -1. */ private int getHeight(TreeNode node, List<List<Integer>> res) { if (null == node) { return -1; } int height = 1 + Math.max(getHeight(node.left, res), getHeight(node.right, res)); if (res.size() == height) { // Current height exceeds result list size. res.add(new ArrayList<>()); } res.get(height).add(node.val); // root.left = root.right = null; return height; } }