{x}
blog image

Binary Tree Level Order Traversal

Given the root of a binary tree, return the level order traversal of its nodes' values. (i.e., from left to right, level by level).

 

Example 1:

Input: root = [3,9,20,null,null,15,7]
Output: [[3],[9,20],[15,7]]

Example 2:

Input: root = [1]
Output: [[1]]

Example 3:

Input: root = []
Output: []

 

Constraints:

  • The number of nodes in the tree is in the range [0, 2000].
  • -1000 <= Node.val <= 1000

Solution Explanation: Binary Tree Level Order Traversal

This problem asks for a level order traversal of a binary tree, meaning we need to visit all nodes level by level, from left to right within each level. The most efficient way to accomplish this is using Breadth-First Search (BFS).

Approach: Breadth-First Search (BFS)

BFS uses a queue data structure to explore the tree. We start by adding the root node to the queue. Then, we iteratively perform the following steps until the queue is empty:

  1. Dequeue: Remove a node from the front of the queue.
  2. Process: Add the node's value to the current level's list.
  3. Enqueue Children: Add the node's left and right children (if they exist) to the back of the queue.
  4. New Level: Once the queue is empty for the current level, add the list of values to the result and start processing the next level (if any).

Code Implementation and Explanation (Python)

from collections import deque
 
class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right
 
class Solution:
    def levelOrder(self, root: TreeNode) -> list[list[int]]:
        result = []
        if not root:  # Handle empty tree case
            return result
 
        queue = deque([root])  # Initialize queue with root node
 
        while queue:
            level_nodes = []
            level_size = len(queue)  # Process nodes for the current level
 
            for _ in range(level_size):
                node = queue.popleft()
                level_nodes.append(node.val)
 
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
 
            result.append(level_nodes)  # Add the level's nodes to the result
 
        return result
 

Line-by-line explanation:

  1. Initialization: We create an empty list result to store the level order traversal. The if not root check handles the case of an empty tree. A deque (double-ended queue) is used for efficient queue operations.

  2. BFS Loop: The while queue loop continues until the queue is empty, indicating that all nodes have been processed.

  3. Level Processing: level_size stores the number of nodes in the current level. The for loop iterates through these nodes.

  4. Node Processing: Inside the loop, we dequeue a node, add its value to level_nodes, and enqueue its children if they exist.

  5. Adding to Result: After processing all nodes at the current level, level_nodes (containing the values for that level) is appended to the result list.

  6. Return Value: Finally, the function returns the result list, which contains lists representing the nodes at each level of the tree.

Time and Space Complexity Analysis

  • Time Complexity: O(N), where N is the number of nodes in the tree. Each node is visited and processed exactly once.

  • Space Complexity: O(W), where W is the maximum width (number of nodes) at any level of the tree. In the worst case (a complete binary tree), W can be approximately N/2, so the space complexity is still considered O(N) in the worst case. This is due to the queue which holds nodes waiting to be processed.

The provided code in other languages follows the same BFS algorithm, adapting the syntax and data structures to the respective languages. The complexity analysis remains the same across all implementations.