嘛,给先序和中序遍历,求右视图。
思路是这样的,首先我们要建树对吧。然后我们对树求右视图。
目录
建树部分
根据先序遍历第一个元素确定根的位置,然后在中序遍历中划分左右子树,求出左右子树长度,在先序遍历中确定左右子树的范围,然后继续递归。
代码如下所示:
TreeNode* buildTree(vector<int>& xianxu,vector<int>& zhongxu,int l1,int r1,int l2,int r2){
if(l1>r1 || l2>r2){
return NULL;
}
int val=xianxu[l1];
int loc=-1;
for(int i=l2;i<=r2;++i){
if(zhongxu[i]==val){
loc=i;
break;
}
}
TreeNode *node=new TreeNode(val);
int leftsize=loc-l2;
int rightsize=r2-loc;
node->left=buildTree(xianxu, zhongxu, l1+1, l1+leftsize, l2, loc-1);
node->right=buildTree(xianxu, zhongxu, l1+leftsize+1, r1, loc+1, r2);
return node;
}
右视图部分
栈
这里用栈怎么想呢?其实队列层序遍历一遍是很好想的。
看到栈,我一开始觉得,那就优先右子树遍历呗,这样应该也可以实现,向右的时候记住深度,用一个map映射,找到一个新的深度就把val放进去。
第二种想法就是正常的先序遍历,这样怎么用栈实现?其实就是左边的都压到栈里面去了,而右子树往往是最先被拿出来的。这样我们就可以一次先序遍历就实现右视图了。
vector<int> rightSideView(TreeNode *root){
unordered_map<int, int> mp;
int max_depth=-1;
stack<TreeNode*>nodes;
stack<int> depths;
nodes.push(root);
depths.push(0);
while(!nodes.empty()){
TreeNode* node=nodes.top();
nodes.pop();
int depth=depths.top();
depths.pop();
if(node!=NULL){
max_depth=max(max_depth, depth);
if(mp.find(depth)==mp.end()){
mp[depth]=node->val;
}
nodes.push(node->left);
nodes.push(node->right);
depths.push(depth+1);
depths.push(depth+1);
}
}
vector<int> res;
for(int i=0;i<=max_depth;++i){
res.push_back(mp[i]);
}
return res;
}
队列
队列是相对好想的,把每一层最后那个输出就行,代码如下:
vector<int> rightSideView(TreeNode *root){
vector<int> res;
queue<TreeNode*>q;
q.push(root);
while(!q.empty()){
int size=q.size();
while(size--){
TreeNode *node=q.front();
q.pop();
if(node->left){
q.push(node->left);
}
if(node->right){
q.push(node->right);
}
if(size==0){
res.push_back(node->val);
}
}
}
return res;
}