题目描述


题目解答
1.层序遍历
这道题需要我们找到每一层最右边的节点,看到层数的时候,我们可以联想到二叉树的层序遍历,可以按顺序获得每一层的节点,那这道题就迎刃而解了。
我们只需要进行一次常规的层序遍历,然后获取每次队列出队的最后一个值,也就是二叉树每一层的最右边的值。然后放入到到结果数组之中。
java
class Solution {
public List<Integer> rightSideView(TreeNode root) {
// 结果列表,存每层最右边的节点值
List<Integer> res = new ArrayList<>();
// 空树返回空列表
if (root == null) {
return res;
}
// 队列辅助层序遍历(BFS)
Deque<TreeNode> queue = new LinkedList<>();
queue.offer(root);
// 外层 while:每轮处理一层
while (!queue.isEmpty()) {
// 当前层的节点数量(必须在循环前固定,因为循环内会入队下一层节点)
int size = queue.size();
// 内层 while:逐个弹出当前层的所有节点
while (size > 0) {
TreeNode cur = queue.poll(); // 弹出队头
size--; // 剩余待处理节点数减 1
// size 减到 0 说明当前节点是这一层的最后一个(最右边)
if (size == 0) {
res.add(cur.val); // 加入结果
}
// 左子入队(下一层才处理)
if (cur.left != null) {
queue.offer(cur.left);
}
// 右子入队(下一层才处理)
if (cur.right != null) {
queue.offer(cur.right);
}
}
}
return res;
}
}
2.前序遍历
这道题要的是"从右边看过去能看到的节点"。这代码用一个 list 来存结果,list 里第 0 个位置放第 0 层看到的节点,第 1 个位置放第 1 层看到的,依此类推。
怎么知道某一层应该放哪个节点呢?------谁先来谁就放进去,后来的没位置了就不放了。 遍历顺序是"根 → 右子树 → 左子树",所以对于每一层来说,最右边的那个节点会第一个到达。第一个到达的提前占好位置,同一层后面的节点再来发现位置已经被占了就自动跳过。
举个例子:根在第 0 层,list 现在是空的,size() <= 0 成立,把根存进去。然后先走根的儿子右子------右子在第 1 层,size() <= 1(list 目前只有一个位置 0),成立,把右子存进去。最后走左子,左子也在第 1 层,但 size() 已经是 2 了(有位置 0 和 1),不等于当前层号 1,说明这层已经有人占位了,自己就不存了。
这样一趟走下来,list 里装的就是每一层"最先到的节点"= 最右边的节点 = 右视图。
java
class Solution {
// 存最终结果:list 的第 i 个位置存的是第 i 层最右边的节点值
List<Integer> list = new ArrayList<>();
public List<Integer> rightSideView(TreeNode root) {
search(root, 0); // 从根节点开始,根在第 0 层
return list;
}
public void search(TreeNode root, Integer level) {
// 走到空节点了,直接回头
if (root == null) {
return;
}
// 如果 list 的大小 ≤ 当前层号,说明这一层还没存过任何节点
// 因为是"根→右→左"的顺序,第一个到达该层的节点就是最右边的节点
if (list.size() <= level) {
list.add(level, root.val); // 在 level 位置插入该节点值
}
// 先走右边,保证右边的节点先被访问到
search(root.right, level + 1);
// 再走左边,作为备选(如果右边没有,才轮到左边)
search(root.left, level + 1);
}
}