Taro Logo

Binary Tree Level Order Traversal

Medium
Amazon logo
Amazon
2 views
Topics:
TreesGraphs

You are given the root of a binary tree. Your task is to return the level order traversal of its nodes' values. This means you should traverse the tree level by level, from left to right, and return a list of lists, where each inner list represents a level.

For example:

  • Example 1:

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

    The tree looks like this:

          3
         / \
        9  20
           /  \
          15   7
    
  • Example 2:

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

    The tree looks like this:

      1
    
  • Example 3:

    • Input: root = []
    • Output: []

    This is an empty tree.

Constraints:

  • The number of nodes in the tree is in the range [0, 2000]. 0 <= number of nodes <= 2000.
  • The value of each node is between -1000 and 1000, inclusive. -1000 <= Node.val <= 1000

Can you implement an algorithm to solve this problem efficiently?

Solution


Level Order Traversal of a Binary Tree

Naive Approach (Breadth-First Search)

The most straightforward way to perform a level order traversal is to use Breadth-First Search (BFS). We can use a queue to keep track of the nodes to visit. At each level, we visit all the nodes at that level before moving on to the next level.

  1. Initialize a queue with the root node.
  2. While the queue is not empty:
    • Get the number of nodes at the current level.
    • Create a list to store the values of the nodes at the current level.
    • Iterate number of nodes at current level times:
      • Dequeue a node from the queue.
      • Add the node's value to the level list.
      • Enqueue the node's left child (if it exists).
      • Enqueue the node's right child (if it exists).
    • Add the level list to the result list.
  3. Return the result list.

Optimal Approach (Breadth-First Search)

The optimal approach is essentially the same as the naive approach since BFS is inherently suited to level order traversal. There is no significant way to improve the algorithmic complexity.

Edge Cases

  • Empty Tree: If the root is null, return an empty list.
  • Single Node Tree: If the tree has only one node, return a list containing a list with the root's value.

Code (Java)

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode() {}
    TreeNode(int val) { this.val = val; }
    TreeNode(int val, TreeNode left, TreeNode right) {
        this.val = val;
        this.left = left;
        this.right = right;
    }
}

class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> result = new ArrayList<>();
        if (root == null) {
            return result;
        }

        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);

        while (!queue.isEmpty()) {
            int levelSize = queue.size();
            List<Integer> currentLevel = new ArrayList<>();

            for (int i = 0; i < levelSize; i++) {
                TreeNode node = queue.poll();
                currentLevel.add(node.val);

                if (node.left != null) {
                    queue.offer(node.left);
                }
                if (node.right != null) {
                    queue.offer(node.right);
                }
            }
            result.add(currentLevel);
        }

        return result;
    }
}

Big O Analysis

  • Time Complexity: O(N), where N is the number of nodes in the binary tree. We visit each node exactly once.
  • Space Complexity: O(W), where W is the maximum width of the binary tree (the maximum number of nodes at any level). In the worst case (a complete binary tree), W is approximately N/2, so the space complexity can be considered O(N).