LeetCode 199 二叉树的右视图
题目描述
给定一棵二叉树,站在树的右侧,从上到下返回能看到的节点。
本质:每一层只取最右侧的节点
解法一:DFS 深度优先搜索(优先右子树)
思路
- 递归遍历,先遍历右子树,再遍历左子树
- 记录当前节点深度,当
depth == 结果集合长度,说明当前层第一次访问节点,也就是本层最右侧节点,直接加入结果集 - 全局集合保存答案,简洁高效
完整代码
java
class Solution {
// 全局集合存储结果
List<Integer> res = new ArrayList<>();
public List<Integer> rightSideView(TreeNode root) {
dfs(root, 0);
return res;
}
// depth:当前节点所在层数(根节点为第0层)
public void dfs(TreeNode root, int depth) {
// 递归终止条件:节点为空直接返回
if(root == null) return;
// 结果集合大小 = 当前层数,说明当前层还没有存入节点,当前节点就是本层最右节点
if(depth == res.size()) {
res.add(root.val);
}
// 核心:先右后左,保证每层最先访问到的是最右侧节点
dfs(root.right, depth+1);
dfs(root.left, depth+1);
}
}
DFS 核心注意点
- 遍历顺序不能颠倒:必须先右后左,先左后右会拿到左视图
- 判断条件
depth == res.size()是精髓,无需记录每一层所有节点,节省空间 - 空间复杂度:最坏链状树 O(H),H为树高
解法二:BFS 广度优先层序遍历
思路
- 借助队列实现二叉树层序遍历,一层一层处理节点
- 记录每一层节点总个数,遍历当前层所有节点
- 每层最后一个节点,就是右视图需要的节点,加入结果集
- 正常先左后右入队,不改变遍历顺序,只取每层末尾元素
完整代码
java
class Solution {
public List<Integer> rightSideView(TreeNode root) {
// 空树直接返回空集合
if(root == null) return new ArrayList<>();
List<Integer> res = new ArrayList<>();
// 队列实现层序遍历
Queue<TreeNode> q = new LinkedList<>();
q.offer(root);
while(!q.isEmpty()) {
// 获取当前层节点总数
int n = q.size();
// 遍历当前整层
for(int i = 0; i < n; i++) {
TreeNode t = q.poll();
// 取当前层最后一个节点
if(i == n - 1) res.add(t.val);
// 左孩子先入队,右孩子后入队,不影响取末尾值
if(t.left != null) q.offer(t.left);
if(t.right != null) q.offer(t.right);
}
}
return res;
}
}
BFS 核心注意点
- 必须提前记录每层节点数量
int n = q.size(),不能直接用队列长度循环 - 入队顺序:左→右完全不影响结果,只需要抓取每层最后一个元素
- 空间复杂度:最坏满二叉树 O(N)
两种方法对比
| 方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| DFS | 空间更小,代码简短 | 递归有栈溢出风险 | 树深度不大,追求代码简洁 |
| BFS | 直观易懂,层序遍历模板通用 | 队列占用空间更大 | 二叉树层序系列题目通用模板 |