Diameter of a Binary Tree

Problem is here: https://leetcode.com/problems/diameter-of-binary-tree/description/

Given a binary tree, you need to compute the length of the diameter of the tree. The diameter of a binary tree is the length of the longest path between any two nodes in a tree. This path may or may not pass through the root.
Example:
Given a binary tree 
          1
         / \
        2   3
       / \     
      4   5    
Return 3, which is the length of the path [4,2,1,3] or [5,2,1,3].
Note: The length of path between two nodes is represented by the number of edges between them.

If you know how to code the height of a binary tree, then you can solve this problem.

Here is the gist of the problem: just think about solving the height of a binary tree problem, which is the classic post-order traversal example:

Height(T)
  T is null ==> 0
  Else ==> Max(Height(T.L), Height(T.R)) + 1

The only difference is that along the calculation you'll be carrying over (by reference) a diameter variable. Before returning within the height function, you'll calculate the value of the diameter variable for the current node. And what's that value?
That value will be the Max between three values: the left diameter, the right diameter, and finally the height of the left node plus the height of the right node plus 1 (itself). Basically what we're saying is that the diameter for the current node is either the best diameter of its children, or the path going thru the node itself. This is all calculated in one line as seen in the code below.
That's it. Good execution time too. Cheers, Marcelo.


public class Solution
{
public int DiameterOfBinaryTree(TreeNode root)
{
int diameter = 0;
Height(root, ref diameter);
return diameter > 0 ? diameter - 1 : diameter;
}

private int Height(TreeNode root, ref int diameter)
{
if (root == null) return 0;

int leftDiameter = 0;
int leftHeight = Height(root.left, ref leftDiameter);
int rightDiameter = 0;
int rightHeight = Height(root.right, ref rightDiameter);

diameter = Math.Max(Math.Max(leftDiameter, rightDiameter), 1 + leftHeight + rightHeight);
return 1 + Math.Max(leftHeight, rightHeight);
}
}

Comments

  1. I love recursion :) My solution is very similar, although I try to avoid mutable parameters and return a struct with max diameter and depth.

    class Solution {
    private:
    struct Result { int diameter; int depth; };
    Result maxDiameterAndDepth(const TreeNode* root) const {
    if (root == nullptr) return {0, 0};
    auto leftResult = maxDiameterAndDepth(root->left);
    auto rightResult = maxDiameterAndDepth(root->right);
    return {
    max({leftResult.diameter, rightResult.diameter, leftResult.depth + rightResult.depth}),
    1 + max(leftResult.depth, rightResult.depth)
    };
    }
    public:
    int diameterOfBinaryTree(const TreeNode* root) const {
    return maxDiameterAndDepth(root).diameter;
    }
    };

    https://gist.github.com/ttsugriy/e1a3e2f4f61cfda6ad70c698ee10de8a

    Cheers,
    Taras

    ReplyDelete

Post a Comment

Popular posts from this blog

Advent of Code - Day 6, 2024: BFS and FSM

Golang vs. C#: performance characteristics (simple case study)

Advent of Code - Day 7, 2024: Backtracking and Eval