二叉树的右视图

122 阅读2分钟

题目描述

leetcode-cn.com/problems/bi…

分析

/**
 * 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) {

};

这道题目只给了 root,二叉树的根节点,一个很自然的想法是递归所有的 root.right,放到一个数组里,但是这个做法是错误的,很显然如果左树层级更深,那么“右视图”看到的一定不是 root.right

所以需要考虑递归的层级,并找到每一层的最右节点

解题思路

记录每一层的最右节点值,放到一个数组里,最终返回

算法

BFS:用广度优先递归每一层 哈希:用一个对象记录节点值

数据结构

queue: 需要用两个栈来存放节点和层级

过程

变量声明

max_depth: 二叉树的最高层次(这个变量也可以不用),初始值为 -1 ,代表没有任何节点 rightMostValue: 对象,记录每一层最右节点的 val, 形式是 depth: val
nodeQueue:放入遍历到的节点,初始值是 [root],因为从根节点开始遍历。在之后的遍历中会把每一层的所有节点都 pushnodeQueuedepthStack:这个栈的每个索引是和上面的 nodeQueue 一一对应的,值代表每个节点的层级

开始广度优先(BFS)遍历

在一次遍历中首先从队首取出一个节点 node,以及它的深度 depth,更新 max_depth

这个节点是 depth 层最右节点

记录 depth 深度的值

将这个深度的值做一次更新在 rightMostValue

⚠️ 这里有一点需要注意,由于广度优先的缘故,我会从左到右进行遍历一层节点,因此只要不断更新,最后记录的就是最右节点值

取出下一层节点

node 的左右节点放入栈

根据栈取出元素是从头,放入在后,所以可以根据这个性质完成广度优先

组装返回值

根据 max_depth 做一个 for 循环来去除所有的 [0, max_depth] 深度的最右节点值,把结果放到一个数组里

代码

/**
 * 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) {
    const nodeQueue = [root]
    const depthQueue = [0]
    const rightMostValue = {}
    let max_depth = -1

    while (nodeQueue.length) {
        const node = nodeQueue.shift()
        const depth = depthQueue.shift()

        if (node) {
            rightMostValue[depth] = node.val
            max_depth = Math.max(max_depth, depth)

            nodeQueue.push(node.left)
            nodeQueue.push(node.right)
            depthQueue.push(depth + 1)
            depthQueue.push(depth + 1)
        }
    }


    const rightView = []
    for (let i = 0; i <= max_depth; i++) {
        rightView.push(rightMostValue[i])
    }

    return rightView
};