[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 }
相关题目