# 0199. 二叉树的右视图 ## 题目地址(199. 二叉树的右视图) <https://leetcode-cn.com/problems/binary-tree-right-side-view/> ## 题目描述 ``` <pre class="calibre18">``` 给定一棵二叉树,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。 示例: 输入: [1,2,3,null,5,null,4] 输出: [1, 3, 4] 解释: 1 <--- / \ 2 3 <--- \ \ 5 4 <--- ``` ``` ## 前置知识 - 队列 ## 公司 - 阿里 - 腾讯 - 百度 - 字节 ## 思路 > 这道题和 leetcode 102 号问题《102.binary-tree-level-order-traversal》很像 这道题可以借助`队列`实现,首先把 root 入队,然后入队一个特殊元素 Null(来表示每层的结束)。 然后就是 while(queue.length), 每次处理一个节点,都将其子节点(在这里是 left 和 right)放到队列中。 然后不断的出队, 如果出队的是 null,则表式这一层已经结束了,我们就继续 push 一个 null。 ## 关键点解析 - 队列 - 队列中用 Null(一个特殊元素)来划分每层 - 树的基本操作- 遍历 - 层次遍历(BFS) - 二叉树的右视图可以看作是层次遍历每次只取每一层的最右边的元素 ## 代码 语言支持:JS,C++ Javascript Code: ``` <pre class="calibre18">``` <span class="hljs-title">/** * @param {TreeNode} root * @return {number[]} */</span> <span class="hljs-keyword">var</span> rightSideView = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">root</span>) </span>{ <span class="hljs-keyword">if</span> (!root) <span class="hljs-keyword">return</span> []; <span class="hljs-keyword">const</span> ret = []; <span class="hljs-keyword">const</span> queue = [root, <span class="hljs-params">null</span>]; <span class="hljs-keyword">let</span> levelNodes = []; <span class="hljs-keyword">while</span> (queue.length > <span class="hljs-params">0</span>) { <span class="hljs-keyword">const</span> node = queue.shift(); <span class="hljs-keyword">if</span> (node !== <span class="hljs-params">null</span>) { levelNodes.push(node.val); <span class="hljs-keyword">if</span> (node.right) { queue.push(node.right); } <span class="hljs-keyword">if</span> (node.left) { queue.push(node.left); } } <span class="hljs-keyword">else</span> { <span class="hljs-title">// 一层遍历已经结束</span> ret.push(levelNodes[<span class="hljs-params">0</span>]); <span class="hljs-keyword">if</span> (queue.length > <span class="hljs-params">0</span>) { queue.push(<span class="hljs-params">null</span>); } levelNodes = []; } } <span class="hljs-keyword">return</span> ret; }; ``` ``` C++ Code: ``` <pre class="calibre18">``` <span class="hljs-title">/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */</span> <span class="hljs-keyword">class</span> Solution { <span class="hljs-keyword">public</span>: <span class="hljs-params">vector</span><<span class="hljs-keyword">int</span>> rightSideView(TreeNode* root) { <span class="hljs-keyword">auto</span> ret = <span class="hljs-params">vector</span><<span class="hljs-keyword">int</span>>(); <span class="hljs-keyword">if</span> (root == <span class="hljs-params">nullptr</span>) <span class="hljs-keyword">return</span> ret; <span class="hljs-keyword">auto</span> q = <span class="hljs-params">queue</span><<span class="hljs-keyword">const</span> TreeNode*>(); q.push(root); <span class="hljs-keyword">while</span> (!q.empty()) { <span class="hljs-keyword">auto</span> sz = q.size(); <span class="hljs-keyword">for</span> (<span class="hljs-keyword">auto</span> i = <span class="hljs-params">0</span>; i < sz; ++i) { <span class="hljs-keyword">auto</span> n = q.front(); q.pop(); <span class="hljs-keyword">if</span> (n->left != <span class="hljs-params">nullptr</span> ) q.push(n->left); <span class="hljs-keyword">if</span> (n->right != <span class="hljs-params">nullptr</span> ) q.push(n->right); <span class="hljs-keyword">if</span> (i == sz - <span class="hljs-params">1</span>) ret.push_back(n->val); } } <span class="hljs-keyword">return</span> ret; } }; ``` ``` ## 扩展 假如题目变成求二叉树的左视图呢? 很简单我们只需要取 queue 的最后一个元素即可。 或者存的时候反着来也行 > 其实我们没必要存储 levelNodes,而是只存储每一层最右的元素,这样空间复杂度就不是 n 了, 就是 logn 了。