LeetCode 199 二叉树的右视图

LeetCode 199 二叉树的右视图

题目描述

给定一棵二叉树,站在树的右侧,从上到下返回能看到的节点。

本质:每一层只取最右侧的节点

解法一:DFS 深度优先搜索(优先右子树)

思路

  1. 递归遍历,先遍历右子树,再遍历左子树
  2. 记录当前节点深度,当 depth == 结果集合长度,说明当前层第一次访问节点,也就是本层最右侧节点,直接加入结果集
  3. 全局集合保存答案,简洁高效

完整代码

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 核心注意点

  1. 遍历顺序不能颠倒:必须先右后左,先左后右会拿到左视图
  2. 判断条件 depth == res.size() 是精髓,无需记录每一层所有节点,节省空间
  3. 空间复杂度:最坏链状树 O(H),H为树高

解法二:BFS 广度优先层序遍历

思路

  1. 借助队列实现二叉树层序遍历,一层一层处理节点
  2. 记录每一层节点总个数,遍历当前层所有节点
  3. 每层最后一个节点,就是右视图需要的节点,加入结果集
  4. 正常先左后右入队,不改变遍历顺序,只取每层末尾元素

完整代码

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 核心注意点

  1. 必须提前记录每层节点数量 int n = q.size(),不能直接用队列长度循环
  2. 入队顺序:左→右完全不影响结果,只需要抓取每层最后一个元素
  3. 空间复杂度:最坏满二叉树 O(N)

两种方法对比

方法 优点 缺点 适用场景
DFS 空间更小,代码简短 递归有栈溢出风险 树深度不大,追求代码简洁
BFS 直观易懂,层序遍历模板通用 队列占用空间更大 二叉树层序系列题目通用模板