1 题目链接
2 题目要求
描述
请根据二叉树的前序遍历,中序遍历恢复二叉树,并打印出二叉树的右视图。
示例
输入:[1,2,4,5,3],[4,2,5,1,3]
返回值:[1,3,5]
备注
二叉树每个节点的值在区间[1,10000]内,且保证每个节点的值互不相同。
3 代码思路
首先如何理解右视图。右视图即二叉树从上到下,每一层最右边的节点组成的集合。
想要输出二叉树的右视图,首先应该根据前序和中序序列创建出二叉树。我们知道前序遍历二叉树顺序是:根节点、遍历左子树、遍历右子树,因此前序遍历数组第一个值即二叉树的根节点。中序遍历二叉树的顺序是:遍历左子树、根节点、遍历右子树,因此我们知道二叉树根节点之后,在中序遍历数组中找到根节点的位置。这个位置之前是左子树的中序遍历数组,之后是右子树的中序遍历数组。遍历同一颗二叉树,前序和中序遍历节点数量是相等的。因此我们知道左右子树的中序遍历数组,通知也知道了左右子树的节点数量,然后再前序遍历数组中找到左右子树的前序遍历数组。递归创建左右子树即可。
构建完成二叉树之后,我们只需要对二叉树进行层次遍历。遍历到每一层时,将该层的最右边节点加入数组即可。
4 代码实现
public class Solution {
public int[] solve (int[] xianxu, int[] zhongxu) {
TreeNode root = build(xianxu, zhongxu, 0, xianxu.length - 1, 0, zhongxu.length - 1);
ArrayList<Integer>list = right(root);
int size = list.size();
int[] result = new int[size];
for(int i = 0; i < size; i++){
result[i] = list.get(i);
}
return result;
}
// 根据前序和中序数组构建二叉树
public TreeNode build(int[] xianxu, int[] zhongxu, int preLeft, int preRight, int inLeft, int inRight){
if(preLeft > preRight || inLeft > inRight)
return null;
// 二叉树的根节点的值
int key = xianxu[preLeft];
TreeNode root = new TreeNode(key);
// 寻找根节点在中序数组中的位置
// 该位置左边是左子树的中序遍历数组
// 右边是右子树的中序遍历数组
int pos;
for(pos = inLeft; pos <= inRight; pos++){
if(zhongxu[pos] == key)
break;
}
// 左子树的节点数量
// 为什么没有计算右子树节点数量,右子树的结尾是inRight和preRight,我们不需要根据pos计算右子树的右边界
int leftCount = pos - inLeft;
root.left = build(xianxu, zhongxu, preLeft + 1, preLeft + leftCount, inLeft, pos - 1);
root.right = build(xianxu, zhongxu, preLeft + leftCount + 1, preRight, pos + 1, inRight);
return root;
}
public ArrayList<Integer> right(TreeNode root){
ArrayList<Integer> result = new ArrayList<Integer>();
if(root == null)
return result;
// 层次遍历
Queue<TreeNode> queue = new LinkedList<TreeNode>();
queue.offer(root);
while(!queue.isEmpty()){
int size = queue.size();
for(int i = 0; i < size; i++){
TreeNode temp = queue.poll();
// 记录每一层的最右边节点
if(i == size - 1) result.add(temp.val);
if(temp.left != null) queue.offer(temp.left);
if(temp.right != null) queue.offer(temp.right);
}
}
return result;
}
}
5 知识补充
5.1 二叉树的遍历
先序遍历
public void preOrder(TreeNode root, ArrayList<Integer> list){
if(root == null)
return;
list.add(root.val);
preOrder(root.left, list);
preOrder(root.right, list);
}
中序遍历
public void inOrder(TreeNode root, ArrayList<Integer> list){
if(root == null)
return;
inOrder(root.left, list);
list.add(root.val);
inOrder(root.right, list);
}
后序遍历
public void postOrder(TreeNode root, ArrayList<Integer> list){
if(root == null)
return;
postOrder(root.left, list);
postOrder(root.right, list);
list.add(root.val);
}
层次遍历
public void levelOrder(TreeNode root, ArrayList<Integer> list){
if(root == null)
return;
Queue<TreeNode> queue = new LinkedList();
queue.offer(root);
while(!queue.isEmpty()){
TreeNode temp = queue.poll();
list.add(temp.val);
if(temp.left != null) queue.offer(temp.left);
if(temp.right != null) queue.offer(temp.right);
}
}