手摸手提桶跑路——LeetCode199. 二叉树的右视图

82 阅读1分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第29天,点击查看活动详情

题目描述

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

示例 1: 捕获.PNG

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

示例 2:

输入: [1,null,3]
输出: [1,3]

示例 3:

输入: []
输出: []

提示:

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

解题思路——BFS 层序遍历

捕获.PNG

我们先看看这张图,题目要求我们给出右视图。这有点像以前上学的时候,有一类题目是几个正方形方块的堆叠,让我们给出其各方位的视图,说白了就是透视。这道题就是这样的。

二叉树的右视图,简单点说,如果最右侧的节点是最长的,那么右视图肯定就是所有最右侧节点的集合了,也就是上面这张图这样,但是题目肯定不会给你这么简单的用例啦。

捕获.PNG

像这种二叉树如果用刚刚的办法岂不是直接 gg 了?

正确的做法应该是层序遍历,然后我们 取每层的最后一个节点,组成的集合就是题目的解,想想是不是这样的?

题解

/**
 * 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 == null) return [];

    let quote = [root], res = [];
    while(quote.length) {
        let lens = quote.length, temp = [];

        for(let i=0; i<lens; ++i) {
            let node = quote.shift();
            temp.push(node.val);
            node.left && quote.push(node.left);
            node.right && quote.push(node.right);
        }
        res.push(temp);
    }

    let concatRes = res.map(arr=>arr.slice(-1)[0])
    return concatRes;
};

解题思路——DFS 深度优先遍历

题目想要的是每层的最后一个节点组成的集合,那么我们可以通过 dfs 深度优先遍历,先访问节点的右子树,将其值存入数组中,表示该层的最右侧节点已经拿到手,下次遍历到该层的其他节点时不用处理。 捕获.PNG 如上图,我们优先访问右节点,这样每层访问都只将右节点放入数组中。

题解

var rightSideView = function(root) {
    if(root == null) return [];
    const res = [];

    const dfs = (root, depth) => {
        if (root == null) return;
        if (depth == res.length) {
            res.push(root.val);
        }
        depth++;
        dfs(root.right, depth);
        dfs(root.left, depth);
    }
    dfs(root, 0);
    return res;
}