题目链接
题目描述
给定一个二叉树的 根节点 root
,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。
题目示例
示例 1 :
输入:root = [1,2,3,null,5,null,4]
输出:[1,3,4]
解释:
示例 2 :
输入:root = [1,2,3,4,null,null,null,5]
输出:[1,3,4,5]
解释:
解题思路
- 问题描述:
给定一棵二叉树的根节点,返回从右侧观察这棵树时能看到的节点值列表(即每一层的最右侧节点)。 - 关键观察:
- 二叉树的右视图实际上是每一层的最右侧节点。
- 如果使用深度优先搜索(DFS),优先访问右子树可以确保每一层第一次访问的节点就是最右侧节点。
- DFS策略:
- 从根节点开始,递归遍历右子树和左子树。
- 维护一个深度变量
depth
,表示当前节点的深度。 - 当
depth
等于结果列表ans
的大小时,说明当前节点是该层第一个被访问的节点(即最右侧节点),将其值加入ans
。
- 递归顺序:
- 先递归右子树,再递归左子树,确保每一层的最右侧节点先被处理。
- 先递归右子树,再递归左子树,确保每一层的最右侧节点先被处理。
题解代码
class Solution {
public List<Integer> rightSideView(TreeNode root) {
List<Integer> ans = new ArrayList<>(); // 存储最终结果的列表
dfs(root, 0, ans); // 从根节点开始深度优先搜索,初始深度为0
return ans; // 返回结果列表
}
private void dfs(TreeNode root, int depth, List<Integer> ans) {
if (root == null) {
return; // 如果当前节点为空,直接返回
}
// 如果当前深度等于结果列表的大小,说明这是该层第一个被访问的节点(最右侧节点)
if (depth == ans.size()) {
ans.add(root.val); // 将该节点的值加入结果列表
}
// 优先递归右子树,确保右子节点先被处理
dfs(root.right, depth + 1, ans);
// 然后递归左子树
dfs(root.left, depth + 1, ans);
}
}
复杂度分析
- 时间复杂度:
- 所有节点都会被访问一次,因此时间复杂度为O(n),其中n是二叉树的节点数。
- 空间复杂度:
- 递归调用栈的空间:取决于树的高度。
- 最坏情况下(树退化为链表),空间复杂度为O(n)。
- 平衡树情况下,空间复杂度为O(log n)。
- 结果列表的空间:存储右视图的节点值,最多有h个元素(h为树的高度),因此空间复杂度为O(h)。
- 递归调用栈的空间:取决于树的高度。