[LeetCode] 199. Binary Tree Right Side View

Given the root of a binary tree, imagine yourself standing on the right side of it, return the values of the nodes you can see ordered from top to bottom.

Example 1:

Input: root = [1,2,3,null,5,null,4]
Output: [1,3,4]

Example 2:

Input: root = [1,null,3]
Output: [1,3]

Example 3:

Input: root = []
Output: []

Constraints:

  • The number of nodes in the tree is in the range [0, 100].
  • -100 <= Node.val <= 100

二叉树的右视图。

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

我给出两种解法,分别是 DFS 和 BFS。

BFS,比较好理解。层序遍历将每个节点加入 queue 之后,只把最后一个节点的值加入结果集。或者是每次加入的时候,一定是先加右孩子,再加左孩子,这样每次拿到每一层的 size 之后,从 queue 中 poll 出的第一个元素就一定是最右边的元素(参见Java实现)。

时间O(n)

空间O(n) - queue

JavaScript实现

 1 /**
 2  * @param {TreeNode} root
 3  * @return {number[]}
 4  */
 5 var rightSideView = function (root) {
 6     let res = [];
 7     let queue = [];
 8     // corner case
 9     if (root === null) return res;
10 
11     // normal case
12     queue.push(root);
13     while (queue.length !== 0) {
14         let size = queue.length;
15         for (let i = 0; i < size; i++) {
16             let cur = queue.shift();
17             if (i === size - 1) {
18                 res.push(cur.val);
19             }
20             if (cur.left !== null) {
21                 queue.push(cur.left);
22             }
23             if (cur.right !== null) {
24                 queue.push(cur.right);
25             }
26         }
27     }
28     return res;
29 };

 

Java实现

 1 class Solution {
 2     public List<Integer> rightSideView(TreeNode root) {
 3         List<Integer> res = new ArrayList<>();
 4         // corner case
 5         if (root == null) {
 6             return res;
 7         }
 8 
 9         // normal case
10         Queue<TreeNode> queue = new LinkedList<>();
11         queue.offer(root);
12         while (!queue.isEmpty()) {
13             int size = queue.size();
14             for (int i = 0; i < size; i++) {
15                 TreeNode cur = queue.poll();
16                 if (i == 0) {
17                     res.add(cur.val);
18                 }
19                 if (cur.right != null) {
20                     queue.offer(cur.right);
21                 }
22                 if (cur.left != null) {
23                     queue.offer(cur.left);
24                 }
25             }
26         }
27         return res;
28     }
29 }

 

DFS

用类似先序遍历的思路但是顺序是根 - 右 - 左,同时多一个变量 level 记录当前深度。如果不加这个变量,就会把树中所有结点都加入结果集。

时间O(n)

空间O(logn), but O(n) for the worse case。这个时候树是退化成了链表。

JavaScript实现

 1 /**
 2  * @param {TreeNode} root
 3  * @return {number[]}
 4  */
 5 var rightSideView = function (root) {
 6     let res = [];
 7     let depth = 0;
 8     dfs(root, res, depth);
 9     return res;
10 };
11 
12 var dfs = function (root, res, depth) {
13     if (root === null) return;
14     if (depth === res.length) {
15         res.push(root.val);
16     }
17     dfs(root.right, res, depth + 1);
18     dfs(root.left, res, depth + 1);
19 }

照着代码跑一下例子。一开始加入根节点1,然后因为当前深度(0)等于res的长度所以把根节点加入res。之后先遍历右子树(3,4),同时深度 + 1(2,3)。这样会分别把3和4也加入res,此时的深度depth是3。当再也没有右子树的时候,深度会回溯至1。当此时再遍历左子树的时候,因为深度(1)跟res长度不等,所以左子树的节点值不加入res。

 

Java实现

 1 /**
 2  * Definition for a binary tree node.
 3  * public class TreeNode {
 4  *     int val;
 5  *     TreeNode left;
 6  *     TreeNode right;
 7  *     TreeNode(int x) { val = x; }
 8  * }
 9  */
10 class Solution {
11     public List<Integer> rightSideView(TreeNode root) {
12         List<Integer> res = new ArrayList<>();
13         if (root == null) return res;
14         helper(res, root, 0);
15         return res;
16     }
17 
18     private void helper(List<Integer> res, TreeNode root, int level) {
19         if (root == null) return;
20         if (res.size() == level) {
21             res.add(root.val);
22         }
23         helper(res, root.right, level + 1);
24         helper(res, root.left, level + 1);
25     }
26 }

 

相关题目

199. Binary Tree Right Side View

545. Boundary of Binary Tree

LeetCode 题目总结

posted @ 2020-02-29 07:39  CNoodle  阅读(218)  评论(0编辑  收藏  举报