leetcode
leetcode 151 ~ 200
二叉树的右视图

二叉树的右视图

难度:

标签:

题目描述

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

 

示例 1:

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

示例 2:

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

示例 3:

输入: []
输出: []

 

提示:

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

代码结果

运行时间: 44 ms, 内存: 14.9 MB


/* 思路: 使用Java Stream来实现右视图。虽然stream并不是解决这个问题的最佳工具,但我们可以使用stream来简化部分操作。 */
 
import java.util.*;
import java.util.stream.*;
 
public class Solution {
    public List<Integer> rightSideView(TreeNode root) {
        if (root == null) return Collections.emptyList();
        List<Integer> result = new ArrayList<>();
        List<TreeNode> currentLevel = new ArrayList<>();
        currentLevel.add(root);
        while (!currentLevel.isEmpty()) {
            result.add(currentLevel.get(0).val); // 右视图节点
            currentLevel = currentLevel.stream()
                    .flatMap(node -> Stream.of(node.right, node.left))
                    .filter(Objects::nonNull)
                    .collect(Collectors.toList());
        }
        return result;
    }
}
 
// 定义二叉树节点类
class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode(int val) { this.val = val; }
}

解释

方法:

该题解采用广度优先遍历(BFS)的思路。使用一个队列来逐层遍历二叉树,对于每一层,记录该层的最后一个节点,即为从右侧能看到的节点。遍历完所有层后,将记录的最后一个节点的值存入结果数组中。

时间复杂度:

O(n)

空间复杂度:

O(n)

代码细节讲解

🦆
在这个BFS算法中,为什么在遍历每一层时只记录最后一个节点的值作为右侧视图的一部分?
在BFS算法中,队列按照从左到右的顺序存储每一层的节点。因此,每次从队列中依次取出节点时,最后一个取出的节点自然是该层最右侧的节点。从右侧视图的角度看,这个节点是唯一可见的,因为它没有被任何同层的节点遮挡。所以,记录每层的最后一个节点能确保正确地从右侧视角构建视图。
🦆
如果二叉树中某些节点值相同,如何确认队列中节点的顺序确实反映了它们在树的结构中的正确位置?
队列中节点的顺序是由节点入队的顺序决定的,这与它们在二叉树中的位置直接相关。在广度优先遍历时,每个节点的子节点按照从左到右的顺序入队。因此,即使某些节点的值相同,它们在队列中的顺序仍然正确反映了它们在树中作为子节点的结构位置。这确保了节点的处理顺序符合其在树中的实际层级和位置。
🦆
题解中提到将非空子节点入队,这里的处理对于包含null子节点的树结构有什么影响?
在BFS遍历中,只有非空子节点会被加入到队列中。这意味着任何为null的子节点都不会进入队列,因此不会参与到层级遍历中。这种处理方法有效地忽略了null子节点,避免了不必要的空指针操作和错误,同时确保队列中的所有节点都是有效的二叉树节点。这样的处理简化了逻辑并提高了代码的效率和安全性。
🦆
给定题目描述中的节点值范围,是否需要考虑处理节点值为负数或特定边界值的特殊情况?
题解中的算法逻辑是基于节点存在与否来进行操作,与节点的具体数值(正数、负数或零)无关。因此,无论节点值是什么,算法的处理逻辑和结构不变。只要确保二叉树的构建正确,节点值本身不会影响算法的执行和结果。因此,不需要对特定的节点值范围进行特殊处理。

相关问题

填充每个节点的下一个右侧节点指针

给定一个 完美二叉树 ,其所有叶子节点都在同一层,每个父节点都有两个子节点。二叉树定义如下:

struct Node {
  int val;
  Node *left;
  Node *right;
  Node *next;
}

填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL

初始状态下,所有 next 指针都被设置为 NULL

 

示例 1:

输入:root = [1,2,3,4,5,6,7]
输出:[1,#,2,3,#,4,5,6,7,#]
解释:给定二叉树如图 A 所示,你的函数应该填充它的每个 next 指针,以指向其下一个右侧节点,如图 B 所示。序列化的输出按层序遍历排列,同一层节点由 next 指针连接,'#' 标志着每一层的结束。

示例 2:

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

 

提示:

  • 树中节点的数量在 [0, 212 - 1] 范围内
  • -1000 <= node.val <= 1000

 

进阶:

  • 你只能使用常量级额外空间。
  • 使用递归解题也符合要求,本题中递归程序占用的栈空间不算做额外的空间复杂度。

二叉树的边界

二叉树的边界