Find the Subtree with the Maximum Average in a Binary Tree using JavaScript
Last Updated :
17 May, 2024
Given a binary tree, our task is to find the subtree with the maximum average in JavaScript. The average of a subtree is defined as the sum of all node values within the subtree divided by the number of nodes it contains.
Example:
Input:
5
/ \
6 7
/ \
3 4
Output: 7
Explanation
Average of values of subtree of node 5 = (5 + 6 + 7+3 +4) / 5 = 5
Average of values of subtree of node 6 = (6+3 +4) / 3 = 4.33
Average of values of subtree of node 7 = 7 / 1 = 7
Average of values of subtree of node 3 = 3 / 1 = 3
Average of values of subtree of node 4 = 4 / 1 = 4
Below are the approaches to finding the subtree with the maximum average in a binary tree using JavaScript:
Brute Force Approach (DFS for each node)
Initialize maxAverage and maxAvgSubtreeR to track the highest average and its corresponding subtree root. Conduct a DFS traversal of the binary tree. For each node, compute the sum of values and the node count using recursive functions subtSum and nodeCount. Determine the subtree's average and update maxAverage and maxAvgSubtreeR if the average is higher. Finally, return the subtree root with the highest average.
Example: The example below shows how to find the subtree with the maximum average in a binary tree using JavaScript.
JavaScript
class TreeNode {
constructor(val) {
this.val = val;
this.left = this.right = null;
}
}
const subtSum = (node) => {
if (!node) return 0;
return node.val + subtSum(node.left)
+ subtSum(node.right);
}
const nodeCount = (node) => {
if (!node) return 0;
return 1 + nodeCount(node.left)
+ nodeCount(node.right);
}
const findMAvgSub = (root) => {
let maxAverage = -Infinity;
let maxAvgStreeR = null;
const dfs = (node) => {
if (!node) return;
const sum = subtSum(node);
const count = nodeCount(node);
const average = sum / count;
if (average > maxAverage) {
maxAverage = average;
maxAvgStreeR = node;
}
dfs(node.left);
dfs(node.right);
};
dfs(root);
return maxAvgStreeR;
};
// Constructing the binary tree
const root1 = new TreeNode(5);
root1.left = new TreeNode(6);
root1.right = new TreeNode(7);
root1.left.left = new TreeNode(3);
root1.left.right = new TreeNode(4);
// Finding the maximum average subtree
const result1 = findMAvgSub(root1);
console.log("Maximum average subtree root value:",
result1.val);
OutputMaximum average subtree root value: 7
Time Complexity: O(n^2), where n is the number of nodes in the binary tree.
Space Complexity: O(h), where h is the height of the binary tree.
Bottom-Up DFS with Recursion
In this method, a bottom-up depth-first search (DFS) is carried out recursively. For every node reached during the traversal, the sum and count of nodes for its left and right subtrees are calculated recursively. Afterward, the sum and count of nodes for the current subtree are determined by adding the sums and counts of its left and right subtrees, alongside the current node. Subsequently, the average of the current subtree is computed, and the maximum average is adjusted accordingly.
Example: The example below shows how to Find the subtree with the maximum average in a binary tree using Bottom-Up DFS with Recursion.
JavaScript
class TreeNode {
constructor(val) {
this.val = val;
this.left = this.right = null;
}
}
const maxAvgSubt = (root) => {
const calSubtreeS = (node) => {
if (!node) return { sum: 0, count: 0 };
const left = calSubtreeS(node.left);
const right = calSubtreeS(node.right);
const sum = left.sum + right.sum + node.val;
const count = left.count + right.count + 1;
return { sum, count };
};
let maxAverage = Number.MIN_SAFE_INTEGER;
const dfs = (node) => {
if (!node) return;
const { sum, count } = calSubtreeS(node);
const average = sum / count;
maxAverage = Math.max(maxAverage, average);
dfs(node.left);
dfs(node.right);
};
dfs(root);
return maxAverage;
};
// Constructing the binary tree
const root2 = new TreeNode(5);
root2.left = new TreeNode(6);
root2.right = new TreeNode(7);
root2.left.left = new TreeNode(3);
root2.left.right = new TreeNode(4);
// Finding the maximum average subtree
const result2 = maxAvgSubt(root2);
console.log("Maximum average subtree:", result2);
OutputMaximum average subtree: 7
Time Complexity: O(n), where n is the number of nodes in the binary tree.
Space Complexity: O(h), where h is the height of the binary tree.
Optimized Bottom-Up DFS with Recursion
In this method, for each node during traversal, recursively calculate the sum and count of nodes for its left and right subtrees. Compute the sum and count of nodes for the current subtree by adding the sums and counts of its left and right subtrees, along with the current node. Calculate the average of the current subtree. Update maxAverage if the average of the current subtree is greater than the current maximum average. Return the maximum average found.
Example: The example below shows how to Find the subtree with the maximum average in a binary tree using Optimized Bottom-Up DFS with Recursion.
JavaScript
class TreeNode {
constructor(val) {
this.val = val;
this.left = this.right = null;
}
}
const maxAvgeSubtree = (root) => {
const dfs = (node) => {
if (!node) return { sum: 0, count: 0 };
const left = dfs(node.left);
const right = dfs(node.right);
const sum = left.sum + right.sum + node.val;
const count = left.count + right.count + 1;
const average = sum / count;
maxAverage = Math.max(maxAverage, average);
return { sum, count };
};
let maxAverage = Number.MIN_SAFE_INTEGER;
dfs(root);
return maxAverage;
};
// Constructing the binary tree
const root3 = new TreeNode(5);
root3.left = new TreeNode(6);
root3.right = new TreeNode(7);
root3.left.left = new TreeNode(3);
root3.left.right = new TreeNode(4);
// Finding the maximum average subtree
const result3 = maxAvgeSubtree(root3);
console.log("Maximum average subtree:", result3);
OutputMaximum average subtree: 7
Time Complexity: O(n), where n is the number of nodes in the binary tree.
Space Complexity: O(h), where h is the height of the binary tree.
Iterative Bottom-Up DFS with Stack
In this approach, for each node encountered during traversal, Use a secondary stack to perform DFS and calculate the sum and count of nodes for the subtree rooted at the current node. Compute the average of the current subtree. Update maxAverage if the average of the current subtree is greater than the current maximum average. Return the maximum average found.
Example: The example below shows how to find the subtree with the maximum average in a binary tree using Iterative Bottom-Up DFS with Stack.
JavaScript
class TreeNode {
constructor(val) {
this.val = val;
this.left = this.right = null;
}
}
const maxAvgeSubtree = (root) => {
let maxAverage = Number.MIN_SAFE_INTEGER;
const stack = [root];
while (stack.length) {
const node = stack.pop();
let sum = 0, count = 0;
const stack2 = [node];
while (stack2.length) {
const curr = stack2.pop();
sum += curr.val;
count++;
if (curr.left) stack.push(curr.left);
if (curr.right) stack.push(curr.right);
}
const average = sum / count;
maxAverage = Math.max(maxAverage, average);
}
return maxAverage;
};
// Constructing the binary tree
const root4 = new TreeNode(5);
root4.left = new TreeNode(6);
root4.right = new TreeNode(7);
root4.left.left = new TreeNode(3);
root4.left.right = new TreeNode(4);
// Finding the maximum average subtree
const result4 = maxAvgeSubtree(root4);
console.log("Maximum average subtree:", result4);
OutputMaximum average subtree: 7
Time Complexity: O(n), where n is the number of nodes in the binary tree.
Space Complexity: O(h), where h is the height of the binary tree.
Top-Down DFS with Memoization
In this approach, each node is encountered during traversal. Recursively calculate the sum and count of nodes for their left and right subtrees, memoizing the results to avoid redundant computations. Compute the sum and count of nodes for the current subtree by adding the sums and counts of its left and right subtrees, along with the current node. Calculate the average of the current subtree. Update maxAverage if the average of the current subtree is greater than the current maximum average. Return the maximum average found.
Example: The example below shows how to find the subtree with the maximum average in a binary tree using Top-Down DFS with Memoization.
JavaScript
class TreeNode {
constructor(val) {
this.val = val;
this.left = this.right = null;
}
}
const maxAvgeSubtree = (root) => {
const memo = new Map();
const dfs = (node) => {
if (!node)
return { sum: 0, count: 0 };
if (memo.has(node))
return memo.get(node);
const left = dfs(node.left);
const right = dfs(node.right);
const sum = left.sum + right.sum + node.val;
const count = left.count + right.count + 1;
const average = sum / count;
memo.set(node, { sum, count });
return { sum, count };
};
let maxAverage = Number.MIN_SAFE_INTEGER;
const calMaxAvg = (node) => {
const { sum, count } = dfs(node);
maxAverage = Math.max(maxAverage, sum / count);
if (node.left) calMaxAvg(node.left);
if (node.right) calMaxAvg(node.right);
};
calMaxAvg(root);
return maxAverage;
};
// Constructing the binary tree
const root5 = new TreeNode(5);
root5.left = new TreeNode(6);
root5.right = new TreeNode(7);
root5.left.left = new TreeNode(3);
root5.left.right = new TreeNode(4);
// Finding the maximum average subtree
const result5 = maxAvgeSubtree(root5);
console.log("Maximum average subtree:", result5);
OutputMaximum average subtree: 7
Time Complexity: O(n), where n is the number of nodes in the binary tree.
Space Complexity: O(n), where n is the number of nodes in the binary tree.
Similar Reads
Find the Mode in a Binary Search Tree using JavaScript
One can find the mode in a binary search tree using JavaScript. The mode in the binary search tree will be the value of the node that occurs with the highest frequency among all the nodes in the tree. If there is more than one mode present in the binary search tree then return all modes present in t
3 min read
Find a Pair with a Given Sum in BST using JavaScript
Given a target sum and Binary Search Tree (BST), we have to write a function to find out the pair of nodes in BST whose values will sum up to this given sum. We must give these two numbers as an array that adds up to get this target sum. If there is no such number pair, return null. Example: Input:
4 min read
Count all K-Sum Paths in a Binary Tree using JavaScript
Given a binary tree and a number k, our task is to find the total number of paths where the sum of the values along the path equals k. The path can start and end at any node in the tree and must go downwards means moving only from parent nodes to child nodes. ApproachDefine a class T_Node representi
2 min read
Kth Ancestor in Binary Tree using JavaScript
Given a binary tree and a node in this tree, our task is to find the k-th ancestor of the specified node in JavaScript. If no such ancestor exists, or when k exceeds the depth of the node, the function should return null. Example: Input: Node = 5, k = 2Output: 1ApproachFirst, calculate the depth of
2 min read
Return the Leftmost Value in the Last Row of the Binary Tree using JavaScript
Given the root of a binary tree, our task is to return the leftmost value in the last row of the binary tree in JavaScript. Here we use recursive and iterative approaches to return the leftmost value in the last row. Explanation: The image below illustrates the leftmost value in the last row of the
3 min read
Insert a Node in Binary tree using JavaScript
A binary tree is a tree data structure where each node has at most two children, referred to as the left child and the right child. The topmost node is called the root. Nodes can have values or data, and the left child's value is less than the parent's value, while the right child's value is greater
3 min read
Find Distance Between Two Nodes of a Binary Tree using JavaScript
In computer science, binary trees are hierarchical data structures that consist of nodes. Each node can have two children at most - one on the leÂft side and one on the right. These structures have a top-to-bottom order. Solving for distance between any two giveÂn nodes is a problem often seÂen w
7 min read
LCA in Binary Tree using JavaScript
The lowest common ancestor between two nodes n1 and n2 in a binary tree is defined as the lowest node in a Tree that has both n1 and n2 as descendants. If either n1 or n2 is not present in the tree, or if they are not connected through a common ancestor, the LCA of the binary tree is NULL. Below is
4 min read
Sum of Left leaves in Binary Tree using JavaScript
Calculating the sum of all left leaves in a binary tree is a common task that helps in understanding tree traversal techniques. A left leaf is defined as a leaf node that is the left child of its parent node. This problem can serve various purposes, such as evaluating symmetry in data structures or
5 min read
Kth Largest/Smallest Element in Binary Search Tree using JavaScript
A binary search tree is a type of binary tree in which each node has two children: left child & right child. In a Binary search tree (BST) all nodes in the left subtree have values less than the node value and all nodes in the right subtree have values greater than the node value. Different appr
4 min read