NC136 输出二叉树的右视图

描述

请根据二叉树的前序遍历,中序遍历恢复二叉树,并打印出二叉树的右视图

示例1

输入:

[1,2,4,5,3],[4,2,5,1,3]

复制返回值:

[1,3,5]

复制

备注:

二叉树每个节点的值在区间[1,10000]内,且保证每个节点的值互不相同。

对于任意一颗树而言,前序遍历的形式总是
[ 根节点, [左子树的前序遍历结果], [右子树的前序遍历结果] ]

即根节点总是前序遍历中的第一个节点。而中序遍历的形式总是
[ [左子树的中序遍历结果], 根节点, [右子树的中序遍历结果] ]

  • 用Map保存中序遍历的值和对应索引,关键可以快速定位每一次根结点的位置

  • 在中序遍历中定位到根节点,知道左子树和右子树中的节点数目。由于同一颗子树的前序遍历和中序遍历的长度显然是相同的,因此我们就可以对应到前序遍历的结果中,
    对上述形式中的所有左右括号进行定位。

  • 递归地构造出左子树和右子树,再将这两颗子树接到根节点的左右位置。
    递归终止条件:当子树先序遍历为空,说明已经越过叶子结点,此时返回null

再通过层序遍历,从左往右,一次入队一层的结点,将每一层结点的最右边结点添加到ArrayList中,因为数组长度需要可以动态扩展,因此先用ArrayList,后面将ArrayList转换为数组

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 求二叉树的右视图
     * @param xianxu int整型一维数组 先序遍历
     * @param zhongxu int整型一维数组 中序遍历
     * @return int整型一维数组
     */
     Map<Integer,Integer>map=new HashMap();
    public int[] solve (int[] xianxu, int[] zhongxu) {
        // write code here

        for(int i=0;i<zhongxu.length;i++)
        {
            map.put(zhongxu[i],i);// 用Map保存中序遍历的值和对应索引
        }
        TreeNode root=build(xianxu,0,xianxu.length-1,zhongxu,0,zhongxu.length-1);
        return bfs(root);

    }
    TreeNode build(int[]xianxu,int xstart,int xend,int[]zhongxu,int zstart,int zend)
    {
        if(xstart>xend)return null;
        int rootval=xianxu[xstart];
        int index=map.get(rootval);//快速定位每一次根结点的位置
        int length=index-zstart;
        TreeNode root=new TreeNode(rootval);//构造根结点
        root.left=build(xianxu,xstart+1,xstart+length,zhongxu,zstart,index-1);//递归构造左子树
        root.right=build(xianxu,xstart+length+1,xend,zhongxu,index+1,zend);//递归构造右子树
        return root;
    }

    int[] bfs(TreeNode root)
    {
        if(root==null)return null;
        Deque<TreeNode>dq=new LinkedList<>();
        List<Integer>list=new ArrayList<>();
        dq.offer(root);
        for(TreeNode temp=root;!dq.isEmpty();)
        {
            //每一层结点数不同,因此队列的大小是不断变化的
            for(int size=dq.size();size>0;size--){
                //每次出队一个结点
                temp=dq.poll();
                if(temp.left!=null)dq.offerLast(temp.left);
                if(temp.right!=null)dq.offerLast(temp.right);

            }
            //数组添加的是每一层最后出队的结点,即最右边的结点
            list.add(temp.val);
        }   
        return list.stream().mapToInt(Integer::valueOf).toArray();
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值