#199
中等
中频
广度优先遍历二叉树的右视图
这是一道围绕树、二叉树、图展开的高频练习。建议先掌握「广度优先遍历」这套写法,再结合下方步骤讲解理解状态维护、边界处理和复杂度取舍。
树
二叉树
图
题目分析
这道题表面上是在处理「二叉树的右视图」,但先要想清楚题目到底让你返回什么,以及过程中哪些约束必须一直满足。从题型上看,它主要在考 树、二叉树 这些能力。这类题通常要按层或按顺序推进,遍历过程中往往还要把附加信息一起带着走。只有先把题目要求翻译成人话,后面的推荐代码才是在实现思路,而不是直接给答案。
接下来怎么看推荐代码: 带着这个理解再看推荐代码时,重点观察这条主线:按层 BFS 遍历二叉树,每层最后一个被处理到的节点值,就是这一层的右视图。
推荐代码
推荐解法:广度优先遍历
时间复杂度: O(n)
空间复杂度: O(n)
核心思路: 按层 BFS 遍历二叉树,每层最后一个被处理到的节点值,就是这一层的右视图。
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
class Solution {
public List<Integer> rightSideView(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();
// 遍历当前层的所有节点
for (int i = 0; i < levelSize; i++) {
TreeNode current = queue.poll();
// 将当前层的最后一个节点加入结果列表(右视图)
if (i == levelSize - 1) {
result.add(current.val);
}
// 将左右子节点加入队列
if (current.left != null) {
queue.offer(current.left);
}
if (current.right != null) {
queue.offer(current.right);
}
}
}
return result;
}
}
// 辅助类(通常由LeetCode提供)
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;
}
}结构化讲解
面试时怎么讲
开场思路
这题我会用 BFS 按层遍历,每层取最右边那个节点。
核心过程
- 队列按层遍历整棵树。
- 每轮先固定当前层节点个数。
- 处理这一层节点时,在最后一个节点处记录答案。
- 继续把左右孩子入队,直到整棵树遍历结束。
复杂度总结
时间复杂度 O(n),空间复杂度 O(n)。
面试补一句:右视图不是特殊遍历,本质上只是层序遍历里的“取层内最后一个”。
核心思路
右视图不是额外的树结构问题,本质上还是按层遍历。只要在每一层抓住最右边那个节点,就能得到站在右侧看到的结果。
步骤讲解
1
先做标准层序遍历
用队列按层处理整棵树,每轮先固定当前层节点数。
为什么这样做:右视图需要按层找代表节点,BFS 是最直接的方法。
对应代码提示:int size = queue.size();
2
记录当前层最后一个节点
在一层的 size 次循环里,最后一次出队的节点就是这一层的最右节点。
为什么这样做:队列按从左到右顺序处理时,层内最后一个节点自然是最右侧。
对应代码提示:if (i == size - 1) answer.add(node.val);
3
继续把孩子节点入队
每个节点处理完后,把左右孩子加入队列,为下一层做准备。
为什么这样做:下一层的右视图同样来自按层处理结果。
对应代码提示:if (node.left != null) queue.offer(node.left);
易错点
没先固定当前层大小
会把下一层节点混进当前层,右视图就不再按层正确。
正确理解:每轮开始先记录
size = queue.size()。记录了每层第一个节点
那其实是左视图,不是右视图。
正确理解:层内最后一个节点才是本题答案。
以为必须先右后左入队
并不是必须,只要层内取最后一个节点即可。
正确理解:更稳的写法是正常左后右入队,然后拿层内最后一个。
复杂度与适用判断
时间复杂度:O(n)
空间复杂度:O(n)
比其他方案更好在哪里:比 DFS 还要额外维护深度首见判断更直观,按层思路更贴题。
适用判断:树题只要答案天然按层产生,优先考虑 BFS。
额外提醒
- 每层最后一个节点就是这一层的右视图代表。
动画演示
如果你还没完全看懂,可以展开动画演示。
广度优先遍历动画演示
想看这段解法是怎么一步步运行的,可以展开动画继续观察。
广度优先遍历动画演示
想看这段解法是怎么一步步运行的,可以展开动画继续观察。
二叉树的右视图
右视图结果:
当前队列:
队列为空
步骤信息:
当前步骤:0
动画演示仅在桌面端提供,移动端请优先阅读推荐代码与结构化讲解。