📝 题目描述
题目链接:二叉树的右视图
给定一个二叉树的 根节点 root,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。
示例:
示例 1:
1 2
| 输入:root = [1,2,3,null,5,null,4] 输出:[1,3,4]
|
示例 2:
1 2
| 输入:root = [1,2,3,4,null,null,null,5] 输出:[1,3,4,5]
|
示例 3:
1 2
| 输入:root = [1,null,3] 输出:[1,3]
|
示例 4:
提示:
二叉树的节点个数的范围是 [0,100]
-100 <= Node.val <= 100
💡 解题思路
方法一:深度优先搜索
我们对树进行深度优先搜索,在搜索过程中,我们总是先访问右子树。那么对于每一层来说,我们在这层见到的第一个结点一定是最右边的结点。
这样一来,我们可以存储在每个深度访问的第一个结点,一旦我们知道了树的层数,就可以得到最终的结果数组。
上图表示了问题的一个实例。红色结点自上而下组成答案,边缘以访问顺序标号。
方法二:广度优先搜索
比较容易想到的方法,借助层序遍历,遍历每一层,保留其最右的节点即可。
🔧 代码实现
1、深度优先搜索
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
| class Solution { public: vector<int> rightSideView(TreeNode* root) { vector<int> ans; if (!root) return ans;
stack<pair<TreeNode*, int>> st; st.push({root, 0});
while (!st.empty()) { auto [node, depth] = st.top(); st.pop();
if (depth == ans.size()) { ans.push_back(node->val); }
if (node->left) st.push({node->left, depth + 1}); if (node->right) st.push({node->right, depth + 1}); }
return ans; } };
|
2、广度优先搜索
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: vector<int> rightSideView(TreeNode* root) { vector<int> ans; if (!root) return ans; queue<TreeNode*> qu; qu.push(root); while(!qu.empty()){ int size = qu.size(); for(int i = 0; i < size - 1; i++) { TreeNode* temp = qu.front(); qu.pop(); if (temp -> left) qu.push(temp -> left); if (temp -> right) qu.push(temp -> right); } TreeNode* temp = qu.front(); qu.pop(); ans.push_back(temp -> val); if (temp -> left) qu.push(temp -> left); if (temp -> right) qu.push(temp -> right); } return ans; } };
|
📊 复杂度分析
1、深度优先搜索
- 时间复杂度:O(n),深度优先搜索最多访问每个结点一次,因此是线性复杂度。
- 空间复杂度:O(n),最坏情况下,栈内会包含接近树高度的结点数量,占用 O(n) 的空间。
2、广度优先搜索
- 时间复杂度:O(n),每个节点最多进队列一次,出队列一次,因此广度优先搜索的复杂度为线性。
- 空间复杂度:O(n),每个节点最多进队列一次,所以队列长度最大不不超过 n,所以这里的空间代价为 O(n)。
🎯 总结