leetcode链接:https://leetcode-cn.com/problems/binary-tree-right-side-view/

题目

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

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

方法一:深度优先遍历

我们先对树进行深度优先搜索,我们总是先访问右子树。
那么对于每一层来说,我们在这层见到的第一个结点一定是最右边的结点。
然后我们存储每个深度访问的第一个节点,一旦我们知道了树的层数,就可以得到最终结果的数组。

image.png

算法:按照 「根结点 -> 右子树 -> 左子树」 的顺序访问, 就可以保证每层都是最先访问最右边的节点的。

  1. class Solution {
  2. List<Integer> res = new ArrayList<>(); //存放最终结果
  3. public List<Integer> rightSideView(TreeNode root) {
  4. dfs(root, 0); // 从根节点开始访问,根节点深度是0
  5. return res;
  6. }
  7. private void dfs(TreeNode root, int depth) {
  8. if (root == null) {
  9. return;
  10. }
  11. // 先访问 当前节点,再递归地访问 右子树 和 左子树。
  12. // 如果当前节点所在深度还没有出现在res里,说明在该深度下当前节点是第一个被访问的节点,
  13. //因此将当前节点加入res中。
  14. if (depth == res.size()) {
  15. res.add(root.val);
  16. }
  17. depth++;
  18. dfs(root.right, depth);
  19. dfs(root.left, depth);
  20. }
  21. }

方法二:广度优先遍历

对二叉树进行层次遍历,所以对于每层来说,最右边的结点一定是最后被遍历到的。【二叉树的层次遍历可以用广度优先搜索实现】
执行广度优先搜索,左结点排在右结点之前,这样,我们对每一层都从左到右访问。因此,只保留每个深度最后访问的结点,我们就可以在遍历完整棵树后得到每个深度最右的结点。

算法:利用广度优先搜索进行层次遍历,记录下每层的最后一个元素。

  1. class Solution {
  2. public List<Integer> rightSideView(TreeNode root) {
  3. List<Integer> res = new ArrayList<>(); //存放最终结果
  4. if (root == null) {
  5. return res;
  6. }
  7. Queue<TreeNode> queue = new LinkedList<>();
  8. queue.offer(root); //根节点入队
  9. while (!queue.isEmpty()) {
  10. int size = queue.size(); //当前队列大小,即当前层的节点个数
  11. for (int i = 0; i < size; i++) {
  12. TreeNode node = queue.poll();
  13. if (node.left != null) {
  14. queue.offer(node.left);
  15. }
  16. if (node.right != null) {
  17. queue.offer(node.right);
  18. }
  19. if (i == size - 1) { //将当前层的最后一个节点放入结果列表
  20. res.add(node.val);
  21. }
  22. }
  23. }
  24. return res;
  25. }
  26. }