4.3. list of depths

This commit is contained in:
anebz 2019-10-25 18:59:04 +02:00
parent 06e9adaba4
commit 8c1c109188
2 changed files with 68 additions and 0 deletions

View File

@ -0,0 +1,67 @@
# 4.3. List of depths
> Given a binary tree, create a linked list of all the nodes at each depth. If you have a tree with depth D, create D linked lists
Create a breadth-first search and at each level create a linked list and append. I don't know how to create a breadth-first algorithm.
## Hints
* A hash table or array mapping from level numbers to nodes at that level might also be helpful
* First come up with an algorithm which does both depth-first search and breadth-first search
## Solution
We can transverse the graph any way we want, as long as we know which level we're on. We can slightly modify the pre-order traversal algorithm, where we pass in `level+1` to the next recursive call.
```java
public static void createLevelLinkedList(TreeNode root, ArrayList<LinkedList<TreeNode>> lists, int level) {
if (root == null) return;
LinkedList<TreeNode> list = null;
if (lists.size() == level) { // Level not contained in list
list = new LinkedList<TreeNode>();
/* Levels are always traversed in order. So, if this is the first time we've visited level i,
* we must have seen levels 0 through i - 1. We can therefore safely add the level at the end. */
lists.add(list);
} else {
list = lists.get(level);
}
list.add(root);
createLevelLinkedList(root.left, lists, level + 1);
createLevelLinkedList(root.right, lists, level + 1);
}
```
Alternatively, we can also implement a modification of the breadth-first search.
```java
public static ArrayList<LinkedList<TreeNode>> createLevelLinkedList(TreeNode root) {
ArrayList<LinkedList<TreeNode>> result = new ArrayList<LinkedList<TreeNode>>();
/* "Visit" the root */
LinkedList<TreeNode> current = new LinkedList<TreeNode>();
if (root != null) {
current.add(root);
}
while (current.size() > 0) {
result.add(current); // Add previous level
LinkedList<TreeNode> parents = current; // Go to next level
current = new LinkedList<TreeNode>();
for (TreeNode parent : parents) {
/* Visit the children */
if (parent.left != null) {
current.add(parent.left);
}
if (parent.right != null) {
current.add(parent.right);
}
}
}
return result;
}
```
Both algorithms run in O(N) time, but space efficiency? The first option uses O(logN) recursive calls (in a balanced tree), each of which adds a new level to the stack. The second solution, which is iterative doesn't need this extra space.
Both solutions require returning O(N) data. The extra O(logN) used in the first approach is dwarfed by the data that must be returned. So both approaches are equally efficient.

View File

@ -47,6 +47,7 @@ If you can't afford to buy the book, you can find a free pdf [here](https://leon
* Find route between nodes in graph * Find route between nodes in graph
* Create minimal binary search tree from array * Create minimal binary search tree from array
* Create a linked list for each depth in the tree
## Chapter 7 Object-oriented design ## Chapter 7 Object-oriented design