一、题目描述
给定一个二叉树的 根节点 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
二、解题思路
- 使用广度优先搜索(BFS)遍历二叉树,从上到下、从左到右进行遍历。
- 在每一层遍历中,取最右侧的节点值,将其添加到结果列表中。
- 返回结果列表。
三、具体代码
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
class Solution {
public List<Integer> rightSideView(TreeNode root) {
// 结果列表
List<Integer> res = new ArrayList<>();
// 如果根节点为空,直接返回空列表
if (root == null) {
return res;
}
// 使用队列实现广度优先搜索
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
// 每一层的节点数量
int size = queue.size();
// 遍历当前层的所有节点
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();
// 如果是当前层的最后一个节点,将其值添加到结果列表
if (i == size - 1) {
res.add(node.val);
}
// 将左子节点加入队列
if (node.left != null) {
queue.offer(node.left);
}
// 将右子节点加入队列
if (node.right != null) {
queue.offer(node.right);
}
}
}
return res;
}
}
四、时间复杂度和空间复杂度
1. 时间复杂度
- 广度优先搜索(BFS)会遍历二叉树中的每个节点一次。
- 对于每个节点,将其添加到队列和从队列中移除的操作是常数时间的,即 O(1)。
- 在每一层,我们需要遍历所有节点,所以对于每个节点,我们最多会执行两次 O(1) 的操作(添加其左右子节点到队列)。
- 假设二叉树有 n 个节点,则总的时间复杂度为 O(n),因为每个节点都只被访问一次。
因此,时间复杂度为 O(n),其中 n 是二叉树中的节点数量。
2. 空间复杂度
- 队列中最多会存储二叉树的一层节点,在最坏的情况下,这一层可能有 n/2 个节点(完全二叉树的最底层)。
- 结果列表 res 最多会存储二叉树的高度 h 个节点,其中 h 是二叉树的高度。
- 在最坏的情况下,二叉树可能退化成一个链表,此时队列和结果列表的空间复杂度都是 O(n)。
因此,空间复杂度为 O(n),其中 n 是二叉树中的节点数量。
五、总结知识点
-
类定义:
class Solution
定义了一个名为Solution
的类。
-
成员方法:
public List<Integer> rightSideView(TreeNode root)
定义了一个公共方法,返回类型为List<Integer>
,接收一个TreeNode
类型的参数。
-
数据结构:
List<Integer>
:一个泛型接口,用于存储整数列表。Queue<TreeNode>
:一个泛型接口,用于实现队列数据结构,这里用于广度优先搜索。ArrayList
:实现了List
接口的可调整大小的数组列表。LinkedList
:实现了List
接口和Queue
接口的链表。
-
条件语句:
if (root == null)
:检查根节点是否为空。
-
循环结构:
while (!queue.isEmpty())
:一个while
循环,用于在队列不为空时持续执行。
-
队列操作:
queue.offer(root)
:将根节点添加到队列的末尾。queue.poll()
:从队列的头部移除并返回元素。queue.size()
:返回队列中的元素数量。
-
逻辑控制:
for (int i = 0; i < size; i++)
:一个for
循环,用于遍历当前层的所有节点。
-
列表操作:
res.add(node.val)
:将元素添加到列表的末尾。
-
递归结构:
- 虽然代码中没有直接使用递归,但是
TreeNode
结构是递归定义的,每个TreeNode
都可能有两个子节点。
- 虽然代码中没有直接使用递归,但是
-
节点访问:
node.left
和node.right
:分别访问二叉树节点的左子节点和右子节点。
-
二叉树遍历:
- 使用广度优先搜索(BFS)来遍历二叉树,通过队列实现层序遍历。
以上就是解决这个问题的详细步骤,希望能够为各位提供启发和帮助。