# 199. 二叉树的右视图

力扣题目链接 (opens new window)

# 题目描述

给定一个二叉树的 根节点 root,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。

示例 1:

输入: root = [1,2,3,null,5,null,4]
输出: [1,3,4]
1
2

示例 2:

输入: root = [1,null,3]
输出: [1,3]
1
2

示例 3:

输入: root = []
输出: []
1
2

提示:

  • 二叉树的节点个数的范围是 [0,100]
  • -100 <= Node.val <= 100

# 思路

什么是"从右侧看到的节点"?就是每一层最右边的那个节点。

想清楚这一点,本题就很简单了:用层序遍历,记录每一层的最后一个节点。

层序遍历用 BFS(广度优先搜索),借助队列实现:

  1. 根节点入队
  2. 每次处理一层的所有节点
  3. 记录该层的最后一个节点值
  4. 将下一层的节点入队
  5. 重复直到队列为空

关键点:怎么知道哪个是每层的最后一个节点?

在处理每一层之前,先记录当前队列的大小 size,这个 size 就是本层节点的数量。遍历完这 size 个节点,最后一个就是该层最右边的节点。

当然,也可以用深度优先搜索(DFS)解决,记录每个深度第一次访问的最右节点。但层序遍历的思路更直观。

# 模拟过程

以 root = [1,2,3,null,5,null,4] 为例:

        1
       / \
      2   3
       \   \
        5   4
1
2
3
4
5

初始化:

  • 队列:[1]
  • 结果:[]

第 1 层 (队列大小 = 1):

  • 处理节点 1,它的左右孩子 2、3 入队
  • 1 是本层最后一个,记录 1
  • 队列:[2,3]
  • 结果:[1]

第 2 层 (队列大小 = 2):

  • 处理节点 2,它的右孩子 5 入队
  • 处理节点 3,它的右孩子 4 入队
  • 3 是本层最后一个,记录 3
  • 队列:[5,4]
  • 结果:[1,3]

第 3 层 (队列大小 = 2):

  • 处理节点 5,无孩子
  • 处理节点 4,无孩子
  • 4 是本层最后一个,记录 4
  • 队列:[]
  • 结果:[1,3,4]

队列为空,遍历结束。

drawio 提示词: 画二叉树的层序遍历过程。第一张展示树结构 [1,2,3,null,5,null,4],从右侧看的视角用虚线或阴影表示,标注能看到的节点 1、3、4。第二张展示层序遍历的三个阶段,每个阶段画出队列状态、当前处理的层(高亮显示)、该层最右节点(用箭头或特殊颜色标注),并在下方列出结果数组的构建过程。两张图画布统一,Logo 放左下角。

文件名:

  • 0199.binary-tree-right-side-view-01-visualization.drawio
  • 0199.binary-tree-right-side-view-02-level-traversal.drawio

# 解题代码

class Solution {
public:
    vector<int> rightSideView(TreeNode* root) {
        vector<int> result;
        if (root == nullptr) return result;
        
        queue<TreeNode*> que;
        que.push(root);
        
        while (!que.empty()) {
            int size = que.size(); // 当前层的节点数
            
            for (int i = 0; i < size; i++) {
                TreeNode* node = que.front();
                que.pop();
                
                if (i == size - 1) { // 本层最后一个节点
                    result.push_back(node->val);
                }
                
                if (node->left) que.push(node->left);
                if (node->right) que.push(node->right);
            }
        }
        
        return result;
    }
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

# 复杂度分析

  • 时间复杂度:O(n),每个节点访问一次
  • 空间复杂度:O(n),队列最多存储一层的节点,最坏情况(完全二叉树最底层)为 n/2

# 其他语言

# Python3

class Solution:
    def rightSideView(self, root: Optional[TreeNode]) -> List[int]:
        if not root:
            return []
        
        result = []
        queue = deque([root])
        
        while queue:
            size = len(queue)
            
            for i in range(size):
                node = queue.popleft()
                
                if i == size - 1:  # 本层最后一个节点
                    result.append(node.val)
                
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
        
        return result
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# Java

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 size = queue.size();
            
            for (int i = 0; i < size; i++) {
                TreeNode node = queue.poll();
                
                if (i == size - 1) { // 本层最后一个节点
                    result.add(node.val);
                }
                
                if (node.left != null) queue.offer(node.left);
                if (node.right != null) queue.offer(node.right);
            }
        }
        
        return result;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

# Go

func rightSideView(root *TreeNode) []int {
    result := []int{}
    if root == nil {
        return result
    }
    
    queue := []*TreeNode{root}
    
    for len(queue) > 0 {
        size := len(queue)
        
        for i := 0; i < size; i++ {
            node := queue[0]
            queue = queue[1:]
            
            if i == size - 1 { // 本层最后一个节点
                result = append(result, node.Val)
            }
            
            if node.Left != nil {
                queue = append(queue, node.Left)
            }
            if node.Right != nil {
                queue = append(queue, node.Right)
            }
        }
    }
    
    return result
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

# JavaScript

var rightSideView = function(root) {
    if (!root) return [];
    
    const result = [];
    const queue = [root];
    
    while (queue.length > 0) {
        const size = queue.length;
        
        for (let i = 0; i < size; i++) {
            const node = queue.shift();
            
            if (i === size - 1) { // 本层最后一个节点
                result.push(node.val);
            }
            
            if (node.left) queue.push(node.left);
            if (node.right) queue.push(node.right);
        }
    }
    
    return result;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# 与代码随想录联系

这道题是层序遍历的经典应用。

我在代码随想录二叉树章节的 102. 二叉树的层序遍历 中详细讲解了层序遍历的模板代码。

层序遍历是二叉树题目中的重要工具,很多题目都可以用它解决:

  • 找每层的最右/最左节点
  • 找每层的最大/最小值
  • 找某一层的节点
  • 之字形遍历

建议录友们把层序遍历的模板代码掌握透彻,后面遇到类似题目就能直接套用。

另外,本题也可以用 DFS 解决,递归时传入深度参数,每个深度只记录第一次从右往左遍历到的节点。但层序遍历的思路更直观,代码也更清晰。

上次更新:: 10/25/2026, 10:24:40 PM

评论

验证登录状态...