🧠
Brute Force (Recursive Level Collection)
💡 This approach uses recursion to collect nodes at each level by traversing the tree multiple times. It is intuitive but inefficient for large trees.
Intuition
We recursively visit nodes and keep track of the current level. For each node, we add its value to a list corresponding to that level. This requires traversing the tree and managing lists for each level.
Algorithm
- Define a helper function that takes a node and its level.
- If the current level list does not exist, create it.
- Add the node's value to the list for that level.
- Recursively call the helper for each child with level + 1.
💡 The recursion depth corresponds to the tree height, and managing the level lists is key to grouping nodes correctly.
from collections import deque
class Node:
def __init__(self, val=None, children=None):
self.val = val
self.children = children if children is not None else []
def levelOrder(root):
res = []
def helper(node, level):
if not node:
return
if len(res) == level:
res.append([])
res[level].append(node.val)
for child in node.children:
helper(child, level + 1)
helper(root, 0)
return res
# Example usage:
if __name__ == '__main__':
root = Node(1, [Node(3, [Node(5), Node(6)]), Node(2), Node(4)])
print(levelOrder(root))
Line Notes
def helper(node, level):Defines recursive function to process nodes by level
if len(res) == level:Checks if we need to add a new list for the current level
res[level].append(node.val)Adds current node's value to its level list
for child in node.children:Recursively processes all children at next level
import java.util.*;
class Node {
public int val;
public List<Node> children;
public Node() {}
public Node(int _val) { val = _val; }
public Node(int _val, List<Node> _children) {
val = _val;
children = _children;
}
}
public class Solution {
public List<List<Integer>> levelOrder(Node root) {
List<List<Integer>> res = new ArrayList<>();
helper(root, 0, res);
return res;
}
private void helper(Node node, int level, List<List<Integer>> res) {
if (node == null) return;
if (res.size() == level) res.add(new ArrayList<>());
res.get(level).add(node.val);
for (Node child : node.children) {
helper(child, level + 1, res);
}
}
// Example usage
public static void main(String[] args) {
Node root = new Node(1, Arrays.asList(
new Node(3, Arrays.asList(new Node(5), new Node(6))),
new Node(2),
new Node(4)
));
Solution sol = new Solution();
System.out.println(sol.levelOrder(root));
}
}
Line Notes
private void helper(Node node, int level, List<List<Integer>> res)Recursive helper to process nodes by level
if (res.size() == level) res.add(new ArrayList<>());Create new list for current level if needed
res.get(level).add(node.val);Add node value to corresponding level list
for (Node child : node.children)Recurse on all children with incremented level
#include <iostream>
#include <vector>
using namespace std;
class Node {
public:
int val;
vector<Node*> children;
Node() {}
Node(int _val) : val(_val) {}
Node(int _val, vector<Node*> _children) : val(_val), children(_children) {}
};
class Solution {
public:
vector<vector<int>> levelOrder(Node* root) {
vector<vector<int>> res;
helper(root, 0, res);
return res;
}
private:
void helper(Node* node, int level, vector<vector<int>>& res) {
if (!node) return;
if (res.size() == level) res.push_back(vector<int>());
res[level].push_back(node->val);
for (Node* child : node->children) {
helper(child, level + 1, res);
}
}
};
int main() {
Node* root = new Node(1, {new Node(3, {new Node(5), new Node(6)}), new Node(2), new Node(4)});
Solution sol;
vector<vector<int>> result = sol.levelOrder(root);
for (auto& level : result) {
for (int val : level) cout << val << ' ';
cout << '\n';
}
return 0;
}
Line Notes
void helper(Node* node, int level, vector<vector<int>>& res)Recursive helper to traverse nodes by level
if (res.size() == level) res.push_back(vector<int>());Add new vector for current level if missing
res[level].push_back(node->val);Append current node's value to its level vector
for (Node* child : node->children)Recurse on each child with incremented level
class Node {
constructor(val, children = []) {
this.val = val;
this.children = children;
}
}
function levelOrder(root) {
const res = [];
function helper(node, level) {
if (!node) return;
if (res.length === level) res.push([]);
res[level].push(node.val);
for (const child of node.children) {
helper(child, level + 1);
}
}
helper(root, 0);
return res;
}
// Example usage
const root = new Node(1, [new Node(3, [new Node(5), new Node(6)]), new Node(2), new Node(4)]);
console.log(levelOrder(root));
Line Notes
function helper(node, level)Recursive helper to process nodes by level
if (res.length === level) res.push([]);Create new array for current level if needed
res[level].push(node.val);Add current node's value to its level array
for (const child of node.children)Recursively call helper on each child with incremented level
Each node is visited once, and we store all nodes in the result. The recursion stack can go as deep as the tree height.
💡 For n=20 nodes, this means roughly 20 visits and storing 20 values, but recursion depth depends on tree height.
Interview Verdict: Accepted but not optimal for very deep trees due to recursion stack
This approach works but risks stack overflow on very deep trees; it is good to understand recursion but not always practical.