Coding Interview Questions | Diameter of Binary Tree
January 2nd, 2024
Diameter of a Binary Tree Problem Introduction:
This summary will talk about my solution to the diameter of a binary tree problem as seen on leetcode here.
How do you solve the Diameter of a Binary Tree problem?:
Solution
const getHeight = (
node: TreeNode | null,
nodeHeightMap: Map<TreeNode, number>
) => {
if (!node) {
return 0;
}
if (nodeHeightMap.has(node)) {
return nodeHeightMap.get(node);
}
const leftHeight = getHeight(node.left, nodeHeightMap);
const rightHeight = getHeight(node.right, nodeHeightMap);
const height = Math.max(leftHeight, rightHeight) + 1;
if (!nodeHeightMap.has(node)) {
nodeHeightMap.set(node, height);
}
return height;
};
function diameterOfBinaryTree(root: TreeNode | null): number {
if (!root) {
return 0;
}
const nodeStack = [root];
let maxHeight = 0;
const nodeHeightMap = new Map<TreeNode, number>();
while (nodeStack.length > 0) {
const currentNode = nodeStack.pop()!;
const currentDiameter =
getHeight(currentNode.left, nodeHeightMap) +
getHeight(currentNode.right, nodeHeightMap);
if (currentDiameter > maxHeight) {
maxHeight = currentDiameter;
}
if (currentNode.left) {
nodeStack.push(currentNode.left);
}
if (currentNode.right) {
nodeStack.push(currentNode.right);
}
}
return maxHeight;
}
Diameter of a Binary Tree Solution Summary:
getHeight
Function - Recursive Height Calculation with Memoization
- Base Case: First we define our base case. If the node is null, return 0.
- Memoization Check: Then, if the height of the node is already calculated, return the stored value.
- Recursive Calls: Next we calculate the height of left and right subtrees using recursion.
- Memoization: Store the calculated height in the
nodeHeightMap
for future reference. - Return: Finally, we return the calculated height to the
diameterOfBinaryTree
function.
diameterOfBinaryTree
Function - Iterative Diameter Calculation Using Stack and Memoization
- Base Case: Again, we define our base case. If the root is null, return 0 (empty tree).
- Initialization: We then initialize a stack (
nodeStack
), maximum diameter (maxHeight
), and a memoization map (nodeHeightMap
). - Main Loop: Then, we perform a stack-based iterative traversal of the tree.
- First we pop a node from the stack.
- Next, we calculate the diameter of the current node using the
getHeight
function. - We then use that calculated height and update
maxHeight
if the current diameter is greater. - Finally, we push left and right child nodes onto the stack if they exist.
Complexities
- Our overall time complexity is
O(n)
as we will iterate through all nodes in the tree once. - Our worst case space complexity is also
O(n)
given the map employed in thegetHeight
function.