1.题目描述
请根据二叉树的前序遍历,中序遍历恢复二叉树,并打印出二叉树的右视图
数据范围: 0≤n≤100000≤n≤10000
要求: 空间复杂度 O(n)O(n),时间复杂度 O(n)O(n)如输入[1,2,4,5,3],[4,2,5,1,3]时,通过前序遍历的结果[1,2,4,5,3]和中序遍历的结果[4,2,5,1,3]可重建出以下二叉树:
所以对应的输出为[1,3,5]。
示例1
输入:
[1,2,4,5,3],[4,2,5,1,3]返回值:
[1,3,5]备注:
二叉树每个节点的值在区间[1,10000]内,且保证每个节点的值互不相同。
2.解题思路
先通过BM40重建二叉树的方法重建出对应的二叉树,然后使用层序遍历该树,每次访问到每一层最右边的结点,将其值加入到答案数组中,最终得到该二叉树的右视图。
3.代码实现
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* 求二叉树的右视图
* @param preOrder int整型一维数组 先序遍历
* @param inOrder int整型一维数组 中序遍历
* @return int整型一维数组
*/
ArrayList<Integer> res = new ArrayList<>();
public int[] solve (int[] preOrder, int[] inOrder) {
// write code here
TreeNode root = reConstructBinaryTree(preOrder, inOrder);
layerOrder(root);
return res.stream().mapToInt(i->i).toArray();
}
/**
* 层序遍历二叉树,将每一层最右边的结点添加到答案中
* @param root
*/
public void layerOrder(TreeNode root) {
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
int sz = queue.size();
for (int i = 0; i < sz; i++) {
TreeNode cur = queue.poll();
if (i == sz - 1) {
res.add(cur.val);
}
if (cur.left != null) {
queue.offer(cur.left);
}
if (cur.right != null) {
queue.offer(cur.right);
}
}
}
}
public TreeNode reConstructBinaryTree (int[] preOrder, int[] vinOrder) {
// write code here
int n = preOrder.length;
if (n == 0) {
return null;
}
TreeNode root = new TreeNode(preOrder[0]);
int idx = 0;
//找根节点在中序序列中的下标idx
for (int i = 0; i < vinOrder.length; i++) {
if (vinOrder[i] == preOrder[0]) {
idx = i;
break;
}
}
//根据下标idx切分出左子树中序和前序序列
//重建左子树
int[] leftVin = Arrays.copyOfRange(vinOrder, 0, idx);
int[] leftPre = Arrays.copyOfRange(preOrder, 1, 1 + leftVin.length);
root.left = reConstructBinaryTree(leftPre, leftVin);
//根据下标idx切分出右子树的中序和前序序列
//重建右子树
int[] rightVin = Arrays.copyOfRange(vinOrder, idx + 1, vinOrder.length);
int[] rightPre = Arrays.copyOfRange(preOrder, 1 + leftPre.length,
1 + leftPre.length + rightVin.length);
root .right = reConstructBinaryTree(rightPre, rightVin);
return root;
}
}