Longest ZigZag Path in a Binary Tree

Updated on 13 June, 2025
Longest ZigZag Path in a Binary Tree header image

Problem Statement

In the context of a binary tree, a ZigZag path is characterized by alternating movement directions starting from any node. The rules for forming this path include:

  • Picking any node as a starting point and selecting an initial direction (either to the right or left child of that node).
  • Following the initial direction to move to the corresponding child node.
  • Once moved, the direction is alternated (from right to left or from left to right).
  • The subsequent steps are repeated by moving into the newly selected direction until further movement is restricted by the absence of child nodes.

Each node traversed contributes to the length of the ZigZag path, with the Zigzag path's length being one less than the count of visited nodes (as a path originally starting with a single node has a length of zero). The task involves computing the length of the longest possible ZigZag path within the provided binary tree.

Examples

Example 1

Input:

root = [1,null,1,1,1,null,null,1,1,null,1,null,null,null,1]

Output:

3

Explanation:

Longest ZigZag path in blue nodes (right -> left -> right).

Example 2

Input:

root = [1,1,1,null,1,null,null,1,1,null,1]

Output:

4

Explanation:

Longest ZigZag path in blue nodes (left -> right -> left -> right).

Example 3

Input:

root = [1]

Output:

0

Constraints

  • The number of nodes in the tree is in the range [1, 5 * 104].
  • 1 <= Node.val <= 100

Approach and Intuition

Analyzing the provided example trees helps us gain insight into the problem and derive an effective approach to find the longest ZigZag path:

  1. Example 1: Input: root = [1,null,1,1,1,null,null,1,1,null,1,null,null,null,1] Output: 3 Explanation: Through the tree traversal, the route traversed (right -> left -> right) maximizes the length of the ZigZag, leading to a path length of 3.

  2. Example 2: Input: root = [1,1,1,null,1,null,null,1,1,null,1] Output: 4 Explanation: For this input, the optimal path follows (left -> right -> left -> right), producing the longest ZigZag sequence observed in the solutions.

  3. Example 3: Input: root = [1] Output: 0 Explanation: Containing only a single node with no children, no movement is possible, making the maximum path length zero.

Given these scenarios, the primary strategy employs a recursive approach to explore each potential starting node and trace all possible ZigZag paths anchored at that node. The recursive strategy alternately explores left and right directions by flipping the movement direction at each depth of recursion. Each node transition updates a local count, which, upon ceasing further motion (node has no children), gets compared against a globally kept maximum to track the longest path encountered.

The constraints of node value ranges and potential large tree sizes necessitate careful handling to avoid inefficient recursions and excessive computational overhead, ensuring that the algorithm remains performant and scalable.

Solutions

  • C++
  • Java
  • Python
cpp
class Solution {
public:
    int maxLength = 0;
    void zigzagSearch(TreeNode* current, bool moveLeft, int length) {
        if (current == nullptr) {
            return;
        }
        maxLength = max(maxLength, length);
        if (moveLeft) {
            zigzagSearch(current->left, false, length + 1);
            zigzagSearch(current->right, true, 1);
        } else {
            zigzagSearch(current->left, false, 1);
            zigzagSearch(current->right, true, length + 1);
        }
    }

    int findLongestZigZag(TreeNode* start) {
        zigzagSearch(start, true, 0);
        return maxLength;
    }
};

The provided C++ code defines a solution for finding the longest ZigZag path in a binary tree. The code is encapsulated in a class named Solution which contains the following components:

  • An integer member variable maxLength initialized to 0 which serves to store the maximum length of the zigzag path found.
  • A recursive function zigzagSearch that performs the main logic to explore the paths in the zigzag manner. This function accepts a TreeNode* indicating the current node, a boolean moveLeft to determine the direction of the movement (left or right), and an integer length which keeps the current length of the zigzag path.
    • The recursive function checks if the current node is nullptr, and if so, it returns immediately as there is no more path to explore.
    • It updates the maxLength with the maximum of its current value and length.
    • Depending on the direction of the movement (stored in moveLeft), it recursively calls itself to continue the exploration either leftward or rightward, appropriately toggling the direction and adjusting the path length.
  • Another function findLongestZigZag initializes the zigzag search from a start node. It calls zigzagSearch starting with a movement directed right and a path length of 0. This function ultimately returns the maxLength, representing the length of the longest ZigZag path found in the tree.

To utilize this solution, instantiate the Solution class and call findLongestZigZag function passing the root node of your binary tree as an argument. This approach employs depth-first search techniques combined with specific direction toggling to effectively identify and measure the longest zigzag path available in the given binary tree.

java
class Solution {
    int maxPath = 0;

    private void zigzagDFS(TreeNode current, boolean leftDirection, int length) {
        if (current == null) {
            return;
        }
        maxPath = Math.max(maxPath, length);
        if (leftDirection) {
            zigzagDFS(current.left, false, length + 1);
            zigzagDFS(current.right, true, 1);
        } else {
            zigzagDFS(current.left, false, 1);
            zigzagDFS(current.right, true, length + 1);
        }
    }

    public int longestZigZag(TreeNode root) {
        zigzagDFS(root, true, 0);
        return maxPath;
    }
}

This Java solution addresses the problem of finding the longest ZigZag path in a binary tree. The solution uses a Depth-First Search (DFS) strategy to traverse the tree and keep track of the path length.

  • The Solution class contains an integer maxPath to store the maximum length of a ZigZag path found during the DFS traversal.
  • Within the zigzagDFS method:
    • Check for a null node to handle the base case where the traversal reaches a leaf node's child.
    • Update maxPath with the maximum value between the current maxPath and the current length.
    • Continue the DFS traversal by choosing the alternate direction each time. If the current direction is left (leftDirection is true), the next recursive call for the left child will switch to right, and vice versa.
  • The longestZigZag method starts the DFS with the root node with an initial direction of true and length 0.
  • Returns the maxPath value after completing the DFS, providing the length of the longest ZigZag path found.

By precisely switching directions during the recursive calls and checking all possible paths, this algorithm effectively finds the longest ZigZag path in the binary tree.

python
class Solution:
    def findMaxZigZag(self, rootNode: Optional[TreeNode]) -> int:
        self.maxLength = 0
        
        def traverseAndCalculate(node, isLeft, length):
            if node:
                self.maxLength = max(self.maxLength, length)
                if isLeft:
                    traverseAndCalculate(node.left, False, length + 1)
                    traverseAndCalculate(node.right, True, 1)
                else:
                    traverseAndCalculate(node.left, False, 1)
                    traverseAndCalculate(node.right, True, length + 1)
        
        traverseAndCalculate(rootNode, True, 0)
        return self.maxLength

The provided Python solution introduces a method to find the longest ZigZag path in a binary tree. The ZigZag path is identified by alternating directions at each node from left to right or right to left. Here's an outline of how the solution works:

  • Initiate a Solution class with the method findMaxZigZag, which takes rootNode, the root node of the binary tree, as its input.

  • Define a local variable maxLength within the findMaxZigZag method to store the length of the longest ZigZag path found during tree traversal.

  • A helper nested function traverseAndCalculate is defined to handle node traversal and ZigZag path length calculation. This function takes three parameters:

    • node: the current node being processed.
    • isLeft: a boolean indicating if the last move was to the left (False indicates a movement to the right).
    • length: the current length of the path.
  • Within traverseAndCalculate, if the current node exists:

    • Update the maxLength if the current path length is longer than any previously recorded path.
    • Depending on the direction from the parent node (isLeft), recursively call traverseAndCalculate for both children of the current node, adjusting the path length and direction appropriately.
  • Initiate the traversal by calling traverseAndCalculate with the rootNode, setting isLeft to True (assuming an initial move from left), and length to 0, indicating the start of path calculation.

  • The method finally returns maxLength, which now holds the length of the longest ZigZag path in the tree.

This Python function is efficient in finding the longest ZigZag path by performing a depth-first search approach, updating the maximum length encountered via the nested helper function. This approach ensures that each node is visited once, maintaining optimal time complexity proportional to the number of nodes in the binary tree.

Comments

No comments yet.