199. 二叉树的右视图
给定一棵二叉树,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。
Solution1(迭代版):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| class Solution { public: vector<int> rightSideView(TreeNode* root) { queue<TreeNode*> q; vector<int> res; if(!root) return res; q.push(root); TreeNode* t = NULL; while(!q.empty()){ int len = q.size(); while(len){ t = q.front();q.pop(); if(t->left) q.push(t->left); if(t->right) q.push(t->right); len--; } res.push_back(t->val); } return res; } };
|
第一种比较符合直觉的就是使用层序遍历,将每一层的最后一个留下。
Solution2(递归版):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| class Solution { public: vector<int> rightSideView(TreeNode* root) { vector<int> res; preorder(root, 1, res); return res; } void preorder(TreeNode* node, int depth, vector<int> & res){ if(!node) return; if(res.size() < depth){ res.push_back(node->val); }else{ res[depth-1] = node->val; } preorder(node->left,depth+1, res); preorder(node->right,depth+1, res); } };
|
使用前序遍历,并且传入层级信息,每到一层,就将该层的信息更新。如果该层没有数据,则新增一层。遍历到最后就会更新为正确的数据。
优化:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| class Solution { public: vector<int> rightSideView(TreeNode* root) { vector<int> res; preorder(root, 0, res); return res; } void preorder(TreeNode* node, int depth, vector<int> & res){ if(!node) return; if(res.size() == depth){ res.push_back(node->val); } preorder(node->right,depth+1, res); preorder(node->left,depth+1, res); } };
|
思路:
仔细观察发现,并没有必要先push进去左节点,碰到右节点再将左节点覆盖掉,而是一开始就直接push进右节点。到左节点的时候就什么事情也不需要做。
每到一个结点优先遍历右节点,res的size++。在遍历左节点的时候直接会跳过。