算法挑战46: 二叉树的右视图

4 阅读2分钟

题目

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

思路

先遍历右子树

再遍历左子树

维护一个深度变量

如果答案长度等于遍历深度,就把节点放进去

这道题是 LeetCode 第 199 题 “二叉树的右视图”

题目要求返回每一层最右边的节点。解决这个问题的关键在于层序遍历,只要我们在遍历每一层时,把最后一个节点的值记录下来,就能得到右视图的结果。

💡 核心思路:层序遍历

想象你站在树的右边,你只能看到每一层最靠右的那个节点。
我们可以使用广度优先搜索,也就是层序遍历。

  1. 使用一个队列来存储每一层的节点。
  2. 每次处理一层时,记录这一层节点的个数 size
  3. 遍历这一层的所有节点。
  4. 当遍历到这一层的最后一个节点(即索引 i === size - 1 时),将它的值加入结果数组。
  5. 同时,将当前节点的左右子节点(如果存在)加入队列,供下一层使用。

💻 代码实现 (JavaScript)

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @return {number[]}
 */
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;
};

🧠 另一种思路:深度优先搜索

除了层序遍历,也可以用深度优先搜索来解决。

思路:
如果我们按照 “根 -> 右 -> 左” 的顺序进行遍历,那么每一层第一个被访问到的节点,一定就是从右边能看到的节点。

我们需要记录当前的深度 depth,如果 depth 等于结果数组的长度,说明这是该层第一次被访问(因为是从右往左遍历),直接加入结果。

var rightSideView = function(root) {
    const result = [];

    function dfs(node, depth) {
        if (!node) return;

        // 如果当前深度等于结果数组长度,说明这是该层第一个访问的节点
        // 因为我们优先遍历右子树,所以这个节点就是最右边的节点
        if (depth === result.length) {
            result.push(node.val);
        }

        // 先遍历右子树,再遍历左子树
        dfs(node.right, depth + 1);
        dfs(node.left, depth + 1);
    }

    dfs(root, 0);
    return result;
};

📌 总结

  • 方法一(层序遍历) :最直观,符合“每一层取一个”的逻辑,推荐使用。
  • 方法二(深度优先搜索) :利用了“先右后左”的遍历顺序,代码更简洁,但逻辑稍微绕一点。