题目描述 这是 LeetCode 上的 199. 二叉树的右视图 ,难度为 中等 。
给定一个二叉树的 根节点 root
,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。
示例 1:
输入: [1 ,2 ,3 ,null ,5 ,null ,4 ] 输出: [1 ,3 ,4 ]
示例 2:
示例 3:
提示:
二叉树的节点个数的范围是 $[0,100]$
$-100 <= Node.val <= 100$
BFS 本质就是找层序遍历过程中,每层的最后一个节点。
Java 代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 class Solution { public List<Integer> rightSideView (TreeNode root) { List<Integer> ans = new ArrayList <>(); if (root == null ) return ans; Deque<TreeNode> d = new ArrayDeque <>(); d.addLast(root); while (!d.isEmpty()) { int sz = d.size(); while (sz-- > 0 ) { TreeNode node = d.pollFirst(); if (node.left != null ) d.addLast(node.left); if (node.right != null ) d.addLast(node.right); if (sz == 0 ) ans.add(node.val); } } return ans; } }
C++ 代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 class Solution {public : vector<int > rightSideView (TreeNode* root) { vector<int > ans; if (!root) return ans; queue<TreeNode*> d; d.push (root); while (!d.empty ()) { int sz = d.size (); while (sz-- > 0 ) { TreeNode* node = d.front (); d.pop (); if (node->left) d.push (node->left); if (node->right) d.push (node->right); if (sz == 0 ) ans.push_back (node->val); } } return ans; } };
Python 代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 class Solution : def rightSideView (self, root: Optional [TreeNode] ) -> List [int ]: ans = [] if not root: return ans d = deque() d.append(root) while d: sz = len (d) while sz > 0 : node = d.popleft() if node.left: d.append(node.left) if node.right: d.append(node.right) if sz == 1 : ans.append(node.val) sz -= 1 return ans
TypeScript 代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 function rightSideView (root: TreeNode | null ): number [] { const ans = []; if (!root) return ans; const d = []; d.push (root); while (d.length > 0 ) { let sz = d.length ; while (sz-- > 0 ) { const node = d.shift ()!; if (node.left ) d.push (node.left ); if (node.right ) d.push (node.right ); if (sz === 0 ) ans.push (node.val ); } } return ans; };
时间复杂度:$O(n)$
空间复杂度:$O(n)$
DFS DFS
解法同理,规定好节点的遍历顺序(例如 中-右-左
),并在 DFS
过程中传递当前层参数 level
(根节点为第 0
层),同时使用一个 Set
数据结构记录处理过的层编号,从而实现只将当前层的首个节点添加到答案中。
Java 代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 class Solution { List<Integer> ans = new ArrayList <>(); Set<Integer> set = new HashSet <>(); public List<Integer> rightSideView (TreeNode root) { dfs(root, 0 ); return ans; } void dfs (TreeNode node, int level) { if (node == null ) return ; if (!set.contains(level)) { ans.add(node.val); set.add(level); } dfs(node.right, level + 1 ); dfs(node.left, level + 1 ); } }
C++ 代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 class Solution {public : vector<int > ans; unordered_set<int > levels; vector<int > rightSideView (TreeNode* root) { dfs (root, 0 ); return ans; } void dfs (TreeNode* node, int level) { if (!node) return ; if (levels.find (level) == levels.end ()) { ans.push_back (node->val); levels.insert (level); } dfs (node->right, level + 1 ); dfs (node->left, level + 1 ); } };
Python 代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 class Solution : def rightSideView (self, root: Optional [TreeNode] ) -> List [int ]: def dfs (node, level ): if not node: return if level not in levels: ans.append(node.val) levels.add(level) dfs(node.right, level + 1 ) dfs(node.left, level + 1 ) ans = [] levels = set () dfs(root, 0 ) return ans
TypeScript 代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 function rightSideView (root: TreeNode | null ): number [] { const ans = []; const levels = new Set (); function dfs (node: TreeNode | null , level: number ) { if (!node) return ; if (!levels.has (level)) { ans.push (node.val ); levels.add (level); } dfs (node.right , level + 1 ); dfs (node.left , level + 1 ); } dfs (root, 0 ); return ans; };
时间复杂度:$O(n)$
空间复杂度:$O(n)$
最后 这是我们「刷穿 LeetCode」系列文章的第 No.198
篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。
在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。
为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode 。
在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。