题解 | #输出二叉树的右视图#

输出二叉树的右视图

https://www.nowcoder.com/practice/c9480213597e45f4807880c763ddd5f0

思路

重建二叉树参考上一题代码,我们从找二叉树右视图来解决

首先通过观察,我们可以看到,右视图节点全部都是二叉树本层最右边的节点,那么有没有一种方法能够直接拿到当层的最右边的节点呢?

很明显我们可以使用层序遍历二叉树,但是我们将每一层的遍历都看做是一次独立的层序遍历,每层的辅助队列的最后一个元素便是右视图节点

即每一层遍历都创建一个新的辅助队列,在遍历开始时计算本层队列长度,除了判断本层是否队列已经为空直接返回,还能用来判断当前出队节点是否为右视图节点

如果是,则将该节点加入右视图节点值集合中

层序遍历完之后集合中的节点值便是右视图节点值,将集合转换为数组返回即可

代码

import java.util.*;


public class Solution {
    /**
    * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
    * 求二叉树的右视图
    *
    * @param pre int整型一维数组 先序遍历
    * @param vin int整型一维数组 中序遍历
    * @return int整型一维数组
    */
    public int[] solve(int[] pre, int[] vin) {
        // 数组判空
        if (pre == null || vin == null || pre.length == 0 || vin.length == 0) {
            return new int[0];
        }
        // 重建二叉树
        TreeNode root = reConstructBinaryTree(pre, vin);
        // 创建辅助队列将根节点加入队列
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        // 创建集合暂存右视图节点值
        List<Integer> rightNodes = new ArrayList<>();
        //层序遍历该二叉树,返回该二叉树的右视图
        layerOrderTraversal(queue, rightNodes);
        // 创建数组
        int[] newNodes = new int[rightNodes.size()];
        // 将集合转换为数组返回
        int length = rightNodes.size();
        for (int i = 0; i < length; i++) {
            newNodes[i] = rightNodes.get(i);
        }
        return newNodes;
    }

    /**
     * 求二叉树的右视图
     *
     * @param queue      当层遍历队列
     * @param rightNodes 右视图节点值集合
     * @apiNote 传入存有二叉树节点队列,返回其右视图值
     * @since 2023/1/7 16:04
     */
    public void layerOrderTraversal(Queue<TreeNode> queue,
                                    List<Integer> rightNodes) {
        // 计算本层队列长度
        int size = queue.size();
        // 如果当层队列长度为零说明已经遍历完毕
        if (size == 0) {
            return;
        }
        // 创建下层遍历队列
        Queue<TreeNode> newQueue = new LinkedList<>();
        // 遍历当层遍历队列找出右视图节点值
        while (!queue.isEmpty()) {
            size--;
            // 如果队列索引为0说明已经是本层最右边节点,将该节点值加入数组
            if (size == 0) {
                rightNodes.add(queue.peek().val);
            }
            // 如果该节点左子树不为空,将该节点加入新队列中
            if (queue.peek().left != null) {
                newQueue.offer(queue.peek().left);
            }
            // 如果该节点右子树不为空,将该节点加入新队列中
            if (queue.peek().right != null) {
                newQueue.offer(queue.peek().right);
            }
            // 让该节点出队
            queue.poll();
        }
        // 进行下一层层序遍历
        layerOrderTraversal(newQueue, rightNodes);
    }

    /**
     * 重建二叉树
     *
     * @param pre 前序遍历数组
     * @param vin 中序遍历数组
     * @return com.gewuyou.algorithm.problem.TreeNode
     * @apiNote 传入前序遍历数组与中序遍历数组,返回重建后的二叉树的根节点
     * @since 2023/1/7 15:20
     */
    public TreeNode reConstructBinaryTree(int[] pre, int[] vin) {
        if (pre == null || vin == null || pre.length == 0 || vin.length == 0) {
            return null;
        }
        return reConstructBinaryTree(pre, vin, 0, pre.length - 1, 0, vin.length - 1);
    }

    /**
     * 重建二叉树的递归方法
     *
     * @param pre      前序遍历数组
     * @param vin      中序遍历数组
     * @param preStart 前序遍历数组上界
     * @param preEnd   前序遍历数组下界
     * @param vinStart 中序遍历上界
     * @param vinEnd   中序遍历下界
     * @return com.gewuyou.algorithm.problem.TreeNode
     * @apiNote
     * @since 2023/1/7 15:22
     */
    public TreeNode reConstructBinaryTree(int[] pre, int[] vin, int preStart,
                                          int preEnd, int vinStart, int vinEnd) {
        // 如果传入上下界越界则返回空节点
        if (preStart > preEnd || vinStart > vinEnd) {
            return null;
        }
        // 创建根节点 前序遍历首节点为根节点
        TreeNode root = new TreeNode(pre[preStart]);
        // 创建遍历中序数组找到根节点所在位置
        int index = 0;
        while (vin[index] != root.val) {
            index++;
        }
        // 计算截取长度
        int lenth = index - vinStart;
        // 分割前序中序数组,递归调用方法返回左右节点
        root.left = reConstructBinaryTree(pre, vin, preStart + 1, preStart + lenth, vinStart,
                                          index - 1);
        root.right = reConstructBinaryTree(pre, vin, preStart + lenth + 1, preEnd,
                                           index + 1, vinEnd);
        // 返回重建后的二叉树
        return root;
    }
}
全部评论

相关推荐

offer多多的六边形战士很无语:看了你的博客,感觉挺不错的,可以把你的访问量和粉丝数在简历里提一下,闪光点(仅个人意见)
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务