You are given the root of a binary tree. A consecutive sequence in a binary tree is a sequence of nodes where each node's value is exactly one greater than the previous node's value. The sequence can go in any direction, i.e., from parent to children or from children to parent.
Your task is to find the length of the longest consecutive sequence in the tree.
For example:
Example 1:
1
\
2
\
3
The longest consecutive sequence is 1 -> 2 -> 3. The length is 3.
Example 2:
2
/ \
1 3
The longest consecutive sequence is 2 -> 3. The length is 2.
Example 3:
1
/ \
2 0
/ /
3 -1
The longest consecutive sequence is 0 -> -1. The length is 2. Another valid one is 1 -> 2 -> 3. The length is 3.
Write a function that takes the root of a binary tree as input and returns the length of the longest consecutive sequence.
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
To find the longest consecutive sequence in a binary tree using a brute force method, we explore every possible path down the tree. We check each path to see if it forms a consecutive sequence, and then we keep track of the longest one we find.
Here's how the algorithm would work step-by-step:
def binary_tree_longest_consecutive_sequence(root):
longest_sequence_length = 0
def explore_paths(node, current_sequence):
nonlocal longest_sequence_length
if not node:
return
# Check if the current node extends the sequence
if not current_sequence or node.val == current_sequence[-1] + 1:
current_sequence.append(node.val)
else:
current_sequence = [node.val]
longest_sequence_length = max(longest_sequence_length, len(current_sequence))
# Explore the left and right subtrees
explore_paths(node.left, current_sequence[:])
explore_paths(node.right, current_sequence[:])
# Initiate the recursive traversal to find the longest sequence
explore_paths(root, [])
return longest_sequence_length
We'll explore the tree by looking at each path from top to bottom. At each step, we check if the current node's value follows the consecutive sequence from its parent. This way, we only focus on promising sequences.
Here's how the algorithm would work step-by-step:
class TreeNode:
def __init__(self, value=0, left=None, right=None):
self.value = value
self.left = left
self.right = right
def longest_consecutive(root):
longest_sequence = 0
def depth_first_search(node, parent_value, current_length):
nonlocal longest_sequence
if not node:
return
# Determine if current node continues sequence.
if parent_value + 1 == node.value:
current_length += 1
else:
# Reset sequence as it's not consecutive.
current_length = 1
# Update the longest sequence found so far.
longest_sequence = max(longest_sequence, current_length)
depth_first_search(node.left, node.value, current_length)
# Explore the right subtree.
depth_first_search(node.right, node.value, current_length)
# Initiate the search at the root.
depth_first_search(root, float('-inf'), 0)
return longest_sequence
Case | How to Handle |
---|---|
Null root node | Return 0 immediately as an empty tree has no consecutive sequence. |
Single node tree | Return 1 as a single node is a sequence of length 1. |
Tree with all identical values | The longest consecutive sequence will be of length 1 because no consecutive numbers exist. |
Left-skewed tree | The algorithm should correctly traverse and identify the longest consecutive sequence, possibly with increased stack depth if recursion is used. |
Right-skewed tree | The algorithm should correctly traverse and identify the longest consecutive sequence, possibly with increased stack depth if recursion is used. |
Very large tree (potential stack overflow with recursion) | Consider iterative approaches using a stack or queue to avoid stack overflow errors with deep trees. |
Integer overflow if node values are extremely large | While unlikely given problem constraints, consider using larger integer types if node values could approach maximum integer values. |
Tree with negative values that can form consecutive sequence | The algorithm should correctly handle negative values when checking for consecutive sequences by comparing to 'node.val + 1'. |