# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def largestValues(self, root: Optional[TreeNode]) -> List[int]:
if not root:
return []
from collections import deque
queue = deque([root])
result = []
while queue:
level_size = len(queue)
max_val = float('-inf')
for _ in range(level_size):
node = queue.popleft()
max_val = max(max_val, node.val)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
result.append(max_val)
return result
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
vector<int> largestValues(TreeNode* root) {
vector<int> result;
if (!root) return result;
queue<TreeNode*> q;
q.push(root);
while (!q.empty()) {
int levelSize = q.size();
int maxVal = INT_MIN;
for (int i = 0; i < levelSize; ++i) {
TreeNode* node = q.front(); q.pop();
if (node->val > maxVal) maxVal = node->val;
if (node->left) q.push(node->left);
if (node->right) q.push(node->right);
}
result.push_back(maxVal);
}
return result;
}
};
/**
* Definition for a binary tree node.
* public 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;
* }
* }
*/
import java.util.*;
class Solution {
public List<Integer> largestValues(TreeNode root) {
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();
int maxVal = Integer.MIN_VALUE;
for (int i = 0; i < levelSize; i++) {
TreeNode node = queue.poll();
maxVal = Math.max(maxVal, node.val);
if (node.left != null) queue.offer(node.left);
if (node.right != null) queue.offer(node.right);
}
result.add(maxVal);
}
return result;
}
}
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {number[]}
*/
var largestValues = function(root) {
if (!root) return [];
let queue = [root];
const result = [];
while (queue.length > 0) {
let levelSize = queue.length;
let maxVal = -Infinity;
for (let i = 0; i < levelSize; i++) {
let node = queue.shift();
maxVal = Math.max(maxVal, node.val);
if (node.left) queue.push(node.left);
if (node.right) queue.push(node.right);
}
result.push(maxVal);
}
return result;
};
You are given the root node of a binary tree. Your task is to find the largest value in each row (or level) of the tree. The tree may be empty, in which case you should return an empty list.
root
.root
is null), return an empty list.To solve this problem, we need to consider how to efficiently visit all nodes in the tree, grouped by their level. The most natural way to process nodes level by level is to use a Breadth-First Search (BFS), which visits all nodes at one depth before moving to the next.
A brute-force approach would be to traverse the tree and, for each node, keep track of its depth and collect values in a dictionary or list by depth. After traversal, we could find the max in each list. However, this is unnecessarily complex since BFS naturally groups nodes by level.
The optimized approach is to use a queue to process nodes level by level. At each level, we track the maximum value seen and add it to the result. This avoids extra data structures and makes the solution both clean and efficient.
We use a queue for BFS because it allows us to efficiently process nodes in the order they appear at each level. Tracking the maximum value per level is straightforward since we know how many nodes to process at each step.
Consider the following binary tree:
1 / \ 3 2 / \ \ 5 3 9
Let's walk through the steps:
The output will be [1, 3, 9]
.
At each level, we process all nodes, update the maximum, and add their children to the queue for the next level.
The BFS approach is optimal for this problem, as it processes each node only once and uses space proportional to the tree's width.
To find the largest value in each row of a binary tree, we use a breadth-first search (BFS) to process nodes level by level. At each level, we track and record the maximum value. This approach is both intuitive and efficient, leveraging the natural structure of the tree and the properties of BFS. The solution is elegant because it requires only a simple queue and a single pass through the tree, making it easy to understand and implement.