请根据二叉树的前序遍历,中序遍历恢复二叉树,并打印出二叉树的右视图
题目描述如下:
请根据二叉树的前序遍历,中序遍历恢复二叉树,并打印出二叉树的右视图
输入:[1,2,4,5,3],[4,2,5,1,3]
返回值:[1,3,5]
本题目可以分为两个部分
- 重构二叉树
- 打印二叉树的右视图
1、重构二叉树思路
对于先序遍历而言,[1,2,4,5,3],列表中的1必定是二叉树的根节点,而中序遍历是左子树、根节点、右子树的顺序,故在[4,2,5,1,3]中根节点1的左边[4,2,5]就是左子树,而【3】就是右子树。
我们可以根据中序遍历的列表求得左右子树的节点数目,从而在先序遍历的列表中得到左右子树的先序遍历。
如示例[1,2,4,5,3],[4,2,5,1,3];
根节点 【1】
左子树的先序遍历【2,4,5】,中序遍历【4,2,5】
右子树的先序遍历【3】,中序遍历【3】
层层递归来构建二叉树。
TreeNode* buildTree(vector<int>& xianxu,int xianxu_l,int xianxu_r,
vector<int>& zhongxu,int zhongxu_l,int zhongxu_r)
{
if(xianxu_l>xianxu_r || zhongxu_l>zhongxu_r)
return nullptr;
TreeNode* root = new TreeNode(xianxu[xianxu_l]); //构建节点
int rootIndex = 0; //用来保存根节点在中序遍历列表的下标
//寻找根节点
for(int i=zhongxu_l;i<=zhongxu_r;i++)
{
if(zhongxu[i] == xianxu[xianxu_l])
{
rootIndex = i;
break;
}
}
int leftSize = rootIndex - zhongxu_l; //左子树大小
int rightSize = zhongxu_r - rootIndex; //右子树大小
//递归构建左子树和右子树
root->left = buildTree(xianxu,xianxu_l+1,xianxu_l+leftSize,
zhongxu,zhongxu_l,zhongxu_l+leftSize-1);
root->right = buildTree(xianxu,xianxu_r-rightSize+1,xianxu_r,
zhongxu,rootIndex+1,zhongxu_r);
return root;
}
2、打印输出二叉树的右视图
二叉树的右视图就是站在二叉树的右边,能看到的节点。如下图

此二叉树的右视图为【3,20,7】
其实本体并没有想象中的那么复杂,思路如下:
如果我们按层序遍历二叉树,每一层都按照先遍历左节点,再遍历右节点的顺序,那么每一层最后遍历的一个节点就是右视图的节点。
//采用左右层序遍历,每一层最后一个节点就是右视图
vector<int> rightView(TreeNode* root)
{
vector<int> res;
queue<TreeNode*> q;
q.push(root);
while(!q.empty())
{
int size = q.size();
while(size--)
{
TreeNode* temp = q.front();
q.pop();
if(temp->left) q.push(temp->left);
if(temp->right) q.push(temp->right);
if(size==0) res.push_back(temp->val);
}
}
return res;
}
完整解题代码如下:
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
* 求二叉树的右视图
* @param xianxu int整型vector 先序遍历
* @param zhongxu int整型vector 中序遍历
* @return int整型vector
*/
vector<int> solve(vector<int>& xianxu, vector<int>& zhongxu) {
// write code here
TreeNode* root = buildTree(xianxu,0,xianxu.size()-1,
zhongxu,0,zhongxu.size()-1);
return rightView(root);
}
TreeNode* buildTree(vector<int>& xianxu,int xianxu_l,int xianxu_r,
vector<int>& zhongxu,int zhongxu_l,int zhongxu_r)
{
if(xianxu_l>xianxu_r || zhongxu_l>zhongxu_r)
return nullptr;
TreeNode* root = new TreeNode(xianxu[xianxu_l]); //构建节点
int rootIndex = 0; //用来保存根节点在中序遍历列表的下标
//寻找根节点
for(int i=zhongxu_l;i<=zhongxu_r;i++)
{
if(zhongxu[i] == xianxu[xianxu_l])
{
rootIndex = i;
break;
}
}
int leftSize = rootIndex - zhongxu_l; //左子树大小
int rightSize = zhongxu_r - rootIndex; //右子树大小
//递归构建左子树和右子树
root->left = buildTree(xianxu,xianxu_l+1,xianxu_l+leftSize,
zhongxu,zhongxu_l,zhongxu_l+leftSize-1);
root->right = buildTree(xianxu,xianxu_r-rightSize+1,xianxu_r,
zhongxu,rootIndex+1,zhongxu_r);
return root;
}
//采用左右层序遍历,每一层最后一个节点就是右视图
vector<int> rightView(TreeNode* root)
{
vector<int> res;
queue<TreeNode*> q;
q.push(root);
while(!q.empty())
{
int size = q.size();
while(size--)
{
TreeNode* temp = q.front();
q.pop();
if(temp->left) q.push(temp->left);
if(temp->right) q.push(temp->right);
if(size==0) res.push_back(temp->val);
}
}
return res;
}
};
根据二叉树的前序遍历和中序遍历,通过递归重构二叉树,并实现打印二叉树的右视图。输入前序遍历和中序遍历,返回二叉树的右视图节点值。示例输入[1,2,4,5,3],[4,2,5,1,3],返回[1,3,5]。"
103821709,7572385,JavaScript数组方法详解,"['javascript', 'js', '数组', '数组方法']
297

被折叠的 条评论
为什么被折叠?



