4.3. list of depths
This commit is contained in:
parent
06e9adaba4
commit
8c1c109188
|
|
@ -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.
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue