💡 This approach uses depth-first traversal but keeps track of levels to aggregate sums and counts, offering an alternative to BFS.
Intuition
Traverse the tree recursively, passing the current level as a parameter, and accumulate sums and counts in arrays indexed by level.
Algorithm
- Initialize two arrays: one for sum of values per level, one for count of nodes per level.
- Define a recursive DFS function that takes a node and its level.
- At each node, add its value to the sum array and increment the count array for that level.
- Recursively call DFS on left and right children with level + 1.
- After traversal, compute averages by dividing sums by counts for each level.
💡 The key is correctly passing and using the level parameter to aggregate data per depth.
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
def averageOfLevels(root):
sums = []
counts = []
def dfs(node, level):
if not node:
return
if level == len(sums):
sums.append(0)
counts.append(0)
sums[level] += node.val
counts[level] += 1
dfs(node.left, level + 1)
dfs(node.right, level + 1)
dfs(root, 0)
return [s / c for s, c in zip(sums, counts)]
# Example usage:
# root = TreeNode(3, TreeNode(9), TreeNode(20, TreeNode(15), TreeNode(7)))
# print(averageOfLevels(root)) # Output: [3.0, 14.5, 11.0]
Line Notes
sums = []Initialize list to store sum of values per level
counts = []Initialize list to store count of nodes per level
def dfs(node, level):Recursive DFS function with level tracking
if level == len(sums):Detect first visit to this level to initialize sums and counts
sums[level] += node.valAdd current node's value to sum for this level
counts[level] += 1Increment count of nodes at this level
dfs(node.left, level + 1)Recurse left child with incremented level
dfs(node.right, level + 1)Recurse right child with incremented level
return [s / c for s, c in zip(sums, counts)]Compute averages after traversal
import java.util.*;
class TreeNode {
int val;
TreeNode left, right;
TreeNode(int val) { this.val = val; }
}
public class Solution {
List<Double> result = new ArrayList<>();
List<Long> sums = new ArrayList<>();
List<Integer> counts = new ArrayList<>();
public List<Double> averageOfLevels(TreeNode root) {
dfs(root, 0);
for (int i = 0; i < sums.size(); i++) {
result.add(sums.get(i) * 1.0 / counts.get(i));
}
return result;
}
private void dfs(TreeNode node, int level) {
if (node == null) return;
if (level == sums.size()) {
sums.add(0L);
counts.add(0);
}
sums.set(level, sums.get(level) + node.val);
counts.set(level, counts.get(level) + 1);
dfs(node.left, level + 1);
dfs(node.right, level + 1);
}
// Example usage:
// public static void main(String[] args) {
// TreeNode root = new TreeNode(3);
// root.left = new TreeNode(9);
// root.right = new TreeNode(20);
// root.right.left = new TreeNode(15);
// root.right.right = new TreeNode(7);
// Solution sol = new Solution();
// System.out.println(sol.averageOfLevels(root));
// }
}
Line Notes
List<Long> sums = new ArrayList<>();Store sum of node values per level using long to avoid overflow
List<Integer> counts = new ArrayList<>();Store count of nodes per level
public List<Double> averageOfLevels(TreeNode root)Main function to return averages
dfs(root, 0);Start DFS traversal from root at level 0
if (level == sums.size())Initialize sums and counts for new level
sums.set(level, sums.get(level) + node.val);Add node value to sum at current level
counts.set(level, counts.get(level) + 1);Increment count at current level
dfs(node.left, level + 1);Recurse left child with incremented level
dfs(node.right, level + 1);Recurse right child with incremented level
result.add(sums.get(i) * 1.0 / counts.get(i));Calculate average for each level
#include <iostream>
#include <vector>
using namespace std;
struct TreeNode {
int val;
TreeNode *left, *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
void dfs(TreeNode* node, int level, vector<long long>& sums, vector<int>& counts) {
if (!node) return;
if (level == sums.size()) {
sums.push_back(0);
counts.push_back(0);
}
sums[level] += node->val;
counts[level]++;
dfs(node->left, level + 1, sums, counts);
dfs(node->right, level + 1, sums, counts);
}
vector<double> averageOfLevels(TreeNode* root) {
vector<double> result;
vector<long long> sums;
vector<int> counts;
dfs(root, 0, sums, counts);
for (int i = 0; i < sums.size(); i++) {
result.push_back((double)sums[i] / counts[i]);
}
return result;
}
// Example usage:
// int main() {
// TreeNode* root = new TreeNode(3);
// root->left = new TreeNode(9);
// root->right = new TreeNode(20);
// root->right->left = new TreeNode(15);
// root->right->right = new TreeNode(7);
// vector<double> averages = averageOfLevels(root);
// for (double avg : averages) cout << avg << " ";
// cout << endl;
// return 0;
// }
Line Notes
void dfs(TreeNode* node, int level, vector<long long>& sums, vector<int>& counts)DFS helper with level tracking and reference to sums and counts
if (level == sums.size())Initialize sums and counts for new level
sums[level] += node->val;Add node value to sum at current level
counts[level]++;Increment count of nodes at this level
dfs(node->left, level + 1, sums, counts);Recurse left child with incremented level
dfs(node->right, level + 1, sums, counts);Recurse right child with incremented level
for (int i = 0; i < sums.size(); i++)Compute averages after traversal
result.push_back((double)sums[i] / counts[i]);Store average for each level
class TreeNode {
constructor(val=0, left=null, right=null) {
this.val = val;
this.left = left;
this.right = right;
}
}
function averageOfLevels(root) {
const sums = [];
const counts = [];
function dfs(node, level) {
if (!node) return;
if (level === sums.length) {
sums.push(0);
counts.push(0);
}
sums[level] += node.val;
counts[level] += 1;
dfs(node.left, level + 1);
dfs(node.right, level + 1);
}
dfs(root, 0);
return sums.map((sum, i) => sum / counts[i]);
}
// Example usage:
// const root = new TreeNode(3, new TreeNode(9), new TreeNode(20, new TreeNode(15), new TreeNode(7)));
// console.log(averageOfLevels(root)); // Output: [3.0, 14.5, 11.0]
Line Notes
const sums = [];Array to accumulate sums per level
const counts = [];Array to count nodes per level
function dfs(node, level)Recursive DFS with level parameter
if (level === sums.length)Initialize sums and counts for new level
sums[level] += node.val;Add node value to sum for current level
counts[level] += 1;Increment count for current level
dfs(node.left, level + 1);Recurse left child with incremented level
dfs(node.right, level + 1);Recurse right child with incremented level
return sums.map((sum, i) => sum / counts[i]);Compute averages after traversal
TimeO(n)
SpaceO(h) where h is the height of the tree due to recursion stack plus O(h) for sums and counts
Each node is visited once in DFS; sums and counts arrays grow with tree height.
💡 For a balanced tree with height ~log n, this uses less memory than BFS queue in wide trees.
Interview Verdict: Accepted
This approach is also efficient and accepted, offering a recursive alternative to BFS.