Taro Logo

Maximum Difference Between Node and Ancestor

Medium
Google logo
Google
1 view
Topics:
TreesRecursion

Given the root of a binary tree, find the maximum value v for which there exist different nodes a and b where v = |a.val - b.val| and a is an ancestor of b.

A node a is an ancestor of b if either: any child of a is equal to b or any child of a is an ancestor of b.

For example:

Consider the following binary tree:

        8
       /  \
      3   10
     / \    \
    1   6   14
       / \   /
      4   7 13

In this tree, we have various ancestor-node differences. Some of these are:

  • |8 - 3| = 5
  • |3 - 7| = 4
  • |8 - 1| = 7
  • |10 - 13| = 3

Among all possible differences, the maximum value is 7 obtained by |8 - 1| = 7.

As another example, consider:

    1
     \
      2
       \
        0
         \
          3

Here the answer is 3 (e.g. |0 - 3|)

Write a function that takes the root of a binary tree and returns the maximum absolute difference between the values of any ancestor and descendant nodes.

Solution


Maximum Difference Between Node and Ancestor

Problem Description

Given the root of a binary tree, the goal is to find the maximum absolute difference v between the values of two different nodes a and b, where a is an ancestor of b. A node a is considered an ancestor of b if b is a descendant of a.

Naive Approach

The most straightforward approach is to traverse the tree and, for each node, check all its descendants to find the maximum difference. This would involve a nested traversal, resulting in a higher time complexity.

  1. For each node in the tree:
    • Perform a traversal of the subtree rooted at that node.
    • For each descendant, calculate the absolute difference between the node's value and the descendant's value.
    • Keep track of the maximum difference found so far.

Complexity Analysis:

  • Time Complexity: O(N^2) in the worst case, where N is the number of nodes in the tree. For each node, we might have to traverse a significant portion of the tree.
  • Space Complexity: O(H), where H is the height of the tree, due to the recursive calls.

Optimal Approach

A more efficient approach involves traversing the tree while keeping track of the minimum and maximum values encountered along the path from the root to the current node. This way, for each node, we can calculate the maximum possible difference with its ancestors in O(1) time.

  1. Maintain min_val and max_val:
    • As we traverse the tree, keep track of the minimum and maximum values encountered from the root to the current node.
  2. Calculate difference:
    • At each node, calculate the absolute difference between the node's value and min_val and max_val.
    • Update the maximum difference found so far.
  3. Recursively Traverse:
    • Recursively traverse the left and right subtrees, updating min_val and max_val as we go.

Code Implementation (Python):

class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right


def maxAncestorDiff(root: TreeNode) -> int:
    def dfs(node, min_val, max_val):
        if not node:
            return 0

        max_diff = max(abs(node.val - min_val), abs(node.val - max_val))

        min_val = min(min_val, node.val)
        max_val = max(max_val, node.val)

        left_diff = dfs(node.left, min_val, max_val)
        right_diff = dfs(node.right, min_val, max_val)

        return max(max_diff, left_diff, right_diff)

    return dfs(root, root.val, root.val)

Complexity Analysis:

  • Time Complexity: O(N), where N is the number of nodes in the tree. We visit each node exactly once.
  • Space Complexity: O(H), where H is the height of the tree, due to the recursive calls. In the worst case (skewed tree), H can be N. In the best case (balanced tree), H is log(N).

Edge Cases

  1. Empty Tree: If the tree is empty (root is None), there are no nodes, and thus no difference. However, the problem statement specifies that there are at least two nodes, so it's not a possible case.
  2. Single Node: If the tree contains only one node, it violates the constraint that there should be two different nodes. The problem states that the number of nodes is in the range [2, 5000], so this case will not happen.
  3. All Nodes with the Same Value: The algorithm correctly handles cases where all node values are the same, returning 0 as the maximum difference.