持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第27天,点击查看活动详情
一、题目
LeetCode 在每个树行中找最大值
给定一棵二叉树的根节点 root ,请找出该二叉树中每一层的最大值。
示例1:
输入: root = [1,3,2,5,3,null,9]
输出: [1,3,9]
示例2:
输入: root = [1,2,3]
输出: [1,3]
提示:
二叉树的节点个数的范围是 [0,104]
-231 <= Node.val <= 231 - 1
二、题解
简单来说可以把二叉树按层来分,然后找到二叉树每一层的节点最大值即可。
方法一
首先可以根据前序遍历来遍历树节点,前序遍历也就是先遍历树的根节点、然后遍历树的左子树节点,最后遍历树的右子树节点。在遍历树节点的时候,需要区分层级,也就是对于同一层的节点,在遍历的过程中,只需要保存记录当前层的节点最大值即可,这样遍历过程中的每一个节点,都是某一层的其中一个节点,就把这个节点值和对于层记录的最大值比较,最终保持每一层都记录这对于层的最大节点值。具体的需要返回的结果是一个数组,数组第一个值就是二叉树第一层的最大值,数组第二个值就是二叉树第二层的最大值,以此类推。这样的话可以再递归遍历树节点的时候同时记录当前层的编号lev,初始的lev为0表示一开始就是第一层,同时也对应数组的第一个元素下标,这样在遍历树节点的过程中,对于是lev层的节点,就保持数组对于lev的下标存储的是最大值即可。
方法二
题目要求寻找每一层的最大值,那么简单的就对二叉树按层遍历,然后计算每一层的最大值即可。具体的要使用一个队列来辅助,初始的将二叉树根节点加入队列,这时队列第一层只有根节点一个节点,然后遍历队列元素节点,将元素节点的子树依次添加到队列,当当前层遍历结束时,队列中的元素都是下一层的节点,对于每一层的节点都可以方便的计算最大值了,最后直到队列中无元素节点就遍历完成了。
三、代码
方法一 Java代码
class Solution {
List<Integer> value = new ArrayList<Integer>();
public List<Integer> largestValues(TreeNode root) {
if (root == null) {
return new ArrayList<Integer>();
}
dfs(root, 0);
return value;
}
public void dfs(TreeNode root, int lev) {
if (lev == value.size()) {
value.add(root.val);
} else {
value.set(lev, Math.max(value.get(lev), root.val));
}
if (root.left != null) {
dfs(root.left, lev + 1);
}
if (root.right != null) {
dfs(root.right, lev + 1);
}
}
}
时间复杂度:O(n),需要遍历一次二叉树的所有节点。
空间复杂度:O(n),要用一个数组记录每一层的节点最大值,以及递归使用的栈空间。
*方法二 Java代码
class Solution {
public List<Integer> largestValues(TreeNode root) {
List<Integer> value = new ArrayList<Integer>();
if (root == null) {
return value;
}
Deque<TreeNode> deque = new ArrayDeque<TreeNode>();
deque.offer(root);
while (!deque.isEmpty()) {
int size = deque.size();
int maxVal = Integer.MIN_VALUE;
while (size-- > 0) {
TreeNode node = deque.poll();
maxVal = Math.max(maxVal, node.val);
if (node.left != null) {
deque.offer(node.left);
}
if (node.right != null) {
deque.offer(node.right);
}
}
value.add(maxVal);
}
return value;
}
}
时间复杂度:O(n),需要遍历一次二叉树的所有节点。
空间复杂度:O(n),要用一个数组记录每一层的节点最大值,以及层序遍历使用队列辅助。