Knowledge Guide
HomeDSATrees

medium Find Largest Value in Each Tree Row

Problem Statement

Given the root of a binary tree, return an array containing the largest value in each row of the tree (0-indexed).

Examples

Example 1

Image
Image

Example 2

Image
Image

Example 3

Constraints:

Try it yourself

Try solving this question here:

✅ Solution Find Largest Value in Each Tree Row

Problem Statement

Given the root of a binary tree, return an array containing the largest value in each row of the tree (0-indexed).

Examples

Example 1

  • Input: root = [1, 2, 3, 4, 5, null, 6]
  • Expected Output: [1, 3, 6]
Image
Image
  • Justification:
    • The first row contains 1. The largest value is 1.
    • The second row has 2 and 3, and the largest is 3.
    • The third row has 4, 5, and 6, and the largest is 6.

Example 2

  • Input: root = [7, 4, 8, 2, 5, null, 9, null, 3]
  • Expected Output: [7, 8, 9, 3]
Image
Image
  • Justification:
    • The first row contains 7, and the largest value is 7.
    • The second row has 4 and 8, and the largest is 8.
    • The third row has 2, 5, and 9, and the largest is 9.
    • The fourth row has 3, and the largest is 3.

Example 3

  • Input: root = [10, 5]
  • Expected Output: [10, 5]
  • Justification:
    • The first row has 10, and the largest value is 10.
    • The second row contains 5, and the largest is 5.

Constraints:

  • The number of nodes in the tree will be in the range [0, 104].
  • -231 <= Node.val <= 231 - 1

Solution

To solve this problem, we need to determine the maximum value at each level (row) of the binary tree. A level order traversal (breadth-first search) is ideal for this task. By traversing each level of the tree one by one, we can find the maximum value in each row and add it to the result list. This approach ensures that every level is fully processed before moving to the next.

Using level order traversal is efficient because it only requires a single pass through the tree, processing each node exactly once. This makes it an optimal solution with a linear time complexity, proportional to the number of nodes in the tree.

Step-by-Step Algorithm

  1. Initialize Result List:

    • Create result as an empty list to store the largest values of each row.
  2. Check for Empty Tree:

    • If root is null, return the empty result list.
  3. Initialize Queue:

    • Create a queue and add root to start level order traversal.
  4. Process Each Level:

    • While the queue is not empty:
      • Determine the number of nodes at the current level (levelSize).
      • Set maxVal to Integer.MIN_VALUE.
  5. Process Each Node at Current Level:

    • For each node in the current level:
      • Dequeue a node, update maxVal with the maximum of maxVal and the node's value.
      • If the node has a left child, enqueue it.
      • If the node has a right child, enqueue it.
  6. Store Largest Value:

    • After processing all nodes at the current level, add maxVal to result.
  7. Repeat for All Levels:

    • Continue until the queue is empty.
  8. Return Result:

    • Return result containing the largest values in each row.

Algorithm Walkthrough

Input: root = [1, 2, 3, 4, 5, null, 6]

Image
Image
  1. Initialize:

    • result = [] (to store largest values)
    • queue = [1] (start with the root node)
  2. Level 1:

    • levelSize = 1 (1 node at this level), maxVal = -∞ (initialize to smallest value)
    • Process Node 1:
      • Dequeue node 1queue = []
      • maxVal = max(-∞, 1) = 1 (update because -∞ is less than 1)
      • Enqueue children 2 and 3queue = [2, 3]
    • Store Largest Value of Level 1:
      • Add 1 to resultresult = [1]
  3. Level 2:

    • levelSize = 2 (2 nodes at this level), maxVal = -∞ (reset for new level)
    • Process Node 2:
      • Dequeue node 2queue = [3]
      • maxVal = max(-∞, 2) = 2 (update because -∞ is less than 2)
      • Enqueue children 4 and 5queue = [3, 4, 5]
    • Process Node 3:
      • Dequeue node 3queue = [4, 5]
      • maxVal = max(2, 3) = 3 (update because 3 is greater than 2)
      • Enqueue child 6queue = [4, 5, 6]
    • Store Largest Value of Level 2:
      • Add 3 to resultresult = [1, 3]
  4. Level 3:

    • levelSize = 3 (3 nodes at this level), maxVal = -∞ (reset for new level)
    • Process Node 4:
      • Dequeue node 4queue = [5, 6]
      • maxVal = max(-∞, 4) = 4 (update because -∞ is less than 4)
    • Process Node 5:
      • Dequeue node 5queue = [6]
      • maxVal = max(4, 5) = 5 (update because 5 is greater than 4)
    • Process Node 6:
      • Dequeue node 6queue = []
      • maxVal = max(5, 6) = 6 (update because 6 is greater than 5)
    • Store Largest Value of Level 3:
      • Add 6 to resultresult = [1, 3, 6]
  5. Return Result:

    • Final output: [1, 3, 6] (largest values from each row).

Code

java
import java.util.*;

// Definition for a binary tree node
// class TreeNode {
//     int val;
//     TreeNode left;
//     TreeNode right;

//     TreeNode(int val) {
//         this.val = val;
//     }
// }

class Solution {

  // Method to find the largest value in each row of the binary tree
  public List<Integer> largestValues(TreeNode root) {
    List<Integer> result = new ArrayList<>();

    // Return an empty list if the root is null
    if (root == null) return result;

    // Initialize a queue for level order traversal
    Queue<TreeNode> queue = new LinkedList<>();
    queue.add(root);

    // Perform level order traversal
    while (!queue.isEmpty()) {
      int levelSize = queue.size();
      int maxVal = Integer.MIN_VALUE;

      // Traverse all nodes at the current level
      for (int i = 0; i < levelSize; i++) {
        TreeNode node = queue.poll();

        // Find the maximum value at the current level
        maxVal = Math.max(maxVal, node.val);

        // Add left and right children to the queue for the next level
        if (node.left != null) queue.add(node.left);
        if (node.right != null) queue.add(node.right);
      }

      // Store the largest value of the current level
      result.add(maxVal);
    }

    return result;
  }

  public static void main(String[] args) {
    Solution solution = new Solution();

    // Example 1: Creating tree for [1, 2, 3, 4, 5, null, 6]
    TreeNode root1 = new TreeNode(1);
    root1.left = new TreeNode(2);
    root1.right = new TreeNode(3);
    root1.left.left = new TreeNode(4);
    root1.left.right = new TreeNode(5);
    root1.right.right = new TreeNode(6);

    List<Integer> output1 = solution.largestValues(root1);
    System.out.println("Example 1 Output: " + output1); // Expected Output: [1, 3, 6]

    // Example 2: Creating tree for [7, 4, 8, 2, 5, null, 9, null, 3]
    TreeNode root2 = new TreeNode(7);
    root2.left = new TreeNode(4);
    root2.right = new TreeNode(8);
    root2.left.left = new TreeNode(2);
    root2.left.right = new TreeNode(5);
    root2.right.right = new TreeNode(9);
    root2.left.left.right = new TreeNode(3);

    List<Integer> output2 = solution.largestValues(root2);
    System.out.println("Example 2 Output: " + output2); // Expected Output: [7, 8, 9, 3]

    // Example 3: Creating tree for [10, 5] using the helper method
    TreeNode root3 = new TreeNode(10);
    root3.left = new TreeNode(5);

    List<Integer> output3 = solution.largestValues(root3);
    System.out.println("Example 3 Output: " + output3); // Expected Output: [10, 5]
  }
}

Complexity Analysis

Time Complexity

  • The algorithm performs a level-order traversal (BFS) of the binary tree. Each node in the tree is visited exactly once, and all nodes are added to the queue at most once.
  • Therefore, the time complexity is , where n is the number of nodes in the binary tree.

Space Complexity

  • The space complexity is mainly determined by the queue used for the level-order traversal. In the worst case, the queue could hold all nodes at the deepest level of the tree. For a balanced binary tree, the maximum number of nodes at the deepest level is approximately n/2, where n is the total number of nodes.
  • Therefore, the space complexity is in the worst case.
🤖 Don't fully get this? Learn it with Claude

Stuck on Find Largest Value in Each Tree Row? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.

🪜 Hint ladder (no spoilers)

Progressively stronger hints — you still solve it.

I'm working on the problem **Find Largest Value in Each Tree Row** (DSA). Give me a HINT LADDER: start with the tiniest nudge, then wait. Only reveal the next, stronger hint when I ask. Do NOT show the full solution unless I type 'show solution'. Keep me doing the thinking. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🎨 Explain the approach visually

See the technique, not just code.

Explain the optimal approach to **Find Largest Value in Each Tree Row** with a VISUAL walkthrough: trace it on a small concrete example using ASCII art / a step-by-step diagram, narrate what changes each step, then give time & space complexity with a one-line derivation. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🔍 Review my solution

Catch bugs, edge cases, sub-optimality.

I'll paste my solution to **Find Largest Value in Each Tree Row**. Review it for correctness, missed edge cases, and time/space complexity, then coach me toward the optimal — don't just rewrite it. Ask me to paste my code now. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🔁 Drill the pattern

Lock in recognition with look-alikes.

Give me 2 problems that use the SAME underlying pattern as **Find Largest Value in Each Tree Row**. For each, let me attempt first, then review my answer and name the trigger signal that reveals the pattern. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.

📝 My notes