LC199
二叉树的右视图
从右侧看树,每一层只会看到最右边的节点
示例树 [1,2,3,null,5,null,4],站在右侧逐层看:depth 0 见 1,depth 1 见 3(2 被挡),depth 2 见 4(5 被挡)→ 答案 [1,3,4]。
二叉树BFS 层序遍历DFS 右优先面试高频
边界测试 · 切换后整段动画会重算
帧 1/20Scene 1
当前步骤
Scene 1:从右侧看树 — 每层只看见最右边的节点
示例树 [1,2,3,null,5,null,4]。想象站在树右侧:同一深度上,更靠右的节点会挡住左边的兄弟。右视图就是每层「从右侧可见」的那一个。
摄像机在树右侧 · ans=[]
二叉树 · 右侧视角
摄像机在右侧ans
[]
右侧视角:同一层从左到右排列,最右节点可见
代码 · 当前高亮行随帧切换
1// BFS · 层序遍历,每层取最后一个2func rightSideViewBFS(root *TreeNode) []int {3 if root == nil { return []int{} }4 ans := []int{}5 queue := []*TreeNode{root}6 for len(queue) > 0 {7 levelSize := len(queue)8 for i := 0; i < levelSize; i++ {9 node := queue[0]10 queue = queue[1:]11 if i == levelSize-1 {12 ans = append(ans, node.Val)13 }14 if node.Left != nil { queue = append(queue, node.Left) }15 if node.Right != nil { queue = append(queue, node.Right) }16 }17 }18 return ans19}2021// DFS · 先右后左,depth 首次记录22func rightSideViewDFS(root *TreeNode) []int {23 ans := []int{}24 var dfs func(*TreeNode, int)25 dfs = func(node *TreeNode, depth int) {26 if node == nil { return }27 if depth == len(ans) {28 ans = append(ans, node.Val)29 }30 dfs(node.Right, depth+1)31 dfs(node.Left, depth+1)32 }33 dfs(root, 0)34 return ans35}
不变量 · 算法为什么对
- · 右视图 = 每一层从右侧可见的最右节点,不是沿 root.Right 一路向下。
- · BFS:levelSize 冻结本层人数,i==levelSize-1 时 append 到 ans。
- · DFS:先右后左,depth==len(ans) 时首次记录该深度节点。
时间线 · 点击跳转
复杂度
BFS
- 时间
- O(n)
- 空间
- O(w)
w 为最大层宽,最坏 O(n)
DFS
- 时间
- O(n)
- 空间
- O(h)
h 为树高,最坏 O(n)
面试回答 · 简短版
这题的本质是每一层只取一个从右侧可见的节点。BFS 做法是层序遍历,每层处理固定 levelSize 个节点,取最后一个加入答案。DFS 做法是先访问右子树,再访问左子树,每个 depth 第一次访问到的节点就是右视图节点。两种方法时间都是 O(n),BFS 空间 O(w),DFS 空间 O(h)。
常见误区
- 误区 1:右视图不是一直沿着 root.Right 走
反例:1→2→5 的锯齿树,答案是 [1,2,5],不是只走右指针。
1 / 2 \ 5 正确答案 [1, 2, 5] — 不是 root.Right 一路向下 - 误区 2:DFS 先左后右会得到左视图
必须先右后左,才能保证每个 depth 第一次到达的是最右节点。
- 误区 3:BFS 忘记固定 levelSize
没有 levelSize 快照会把下一层节点混进当前层,取「最后一个」就错了。
迁移练习
- →LC102 层序遍历:理解 levelSize
- →LC515 每层最大值:同样是逐层统计
- →左视图变体:DFS 先左后右 / BFS 取每层第一个