剑指offer_043 往完全二叉树添加节点

题目:

完全二叉树是每一层(除最后一层外)都是完全填充(即,节点数达到最大,第 n 层有 2n-1 个节点)的,并且所有的节点都尽可能地集中在左侧。

设计一个用完全二叉树初始化的数据结构 CBTInserter,它支持以下几种操作:

CBTInserter(TreeNode root) 使用根节点为 root 的给定树初始化该数据结构;
CBTInserter.insert(int v)  向树中插入一个新节点,节点类型为 TreeNode,值为 v 。使树保持完全二叉树的状态,并返回插入的新节点的父节点的值;
CBTInserter.get_root() 将返回树的根节点。

示例 1:

输入:inputs = ["CBTInserter","insert","get_root"], inputs = [[[1]],[2],[]]
输出:[null,1,[1,2]]

示例 2:

输入:inputs = ["CBTInserter","insert","insert","get_root"], inputs = [[[1,2,3,4,5,6]],[7],[8],[]]
输出:[null,3,4,[1,2,3,4,5,6,7,8]]

提示:

最初给定的树是完全二叉树,且包含 1 到 1000 个节点。
每个测试用例最多调用 CBTInserter.insert  操作 10000 次。
给定节点或插入节点的每个值都在 0 到 5000 之间。

代码:

package jianzhi;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;

public class offer_43 {

    // 初始化节点
    public class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;

        TreeNode() {
        }

        TreeNode(int val) {
            this.val = val;
        }

        TreeNode(int val, TreeNode left, TreeNode right) {
            this.val = val;
            this.left = left;
            this.right = right;
        }
    }

    // 队列
    class CBTInserter {

        // 根节点
        TreeNode root;
        // 初始化一个用来存储子节点未满的节点的队列
        Queue<TreeNode> notFull = new LinkedList<>();

        // 把子节点未满的节点放入队列
        public CBTInserter(TreeNode root) {

            //初始化根节点
            this.root = root;

            // 初始化一个队列用来存储子节点已满的队列
            Queue<TreeNode> temp = new LinkedList<>();
            temp.offer(root);
            /**
             * 1、把根节点加入队列
             * 2、取出队列中的队头节点,如果子节点不满,则将此节点加入
             * 3、然后依次把该节点的左右子节点加入队列
             * 4、重复步骤二和步骤三,直到队列为空,此时所有不满的节点都已经加入了 notFull 队列
             */
            while (!temp.isEmpty()) {
                TreeNode t = temp.poll();
                if (t.left == null || t.right == null) {
                    // 把不满的节点放入temp
                    notFull.offer(t);
                }
                if (t.left != null) {
                    temp.offer(t.left);
                }
                if (t.right != null) {
                    temp.offer(t.right);
                }
            }

        }

        /**
         * 加入节点返回父节点的值
         * 1、先查看队头节点的左子树是否为空,如果为空则把该节点加入到左子树
         * 2、左子树不为空的话则把该节点加入到队头节点,此时队头节点的子节点已满,移出 notFull 队列
         * @param v
         * @return
         */
        public int insert(int v) {
            TreeNode t = notFull.peek();
            if (t.left == null) {
                t.left = new TreeNode(v);
                notFull.offer(t.left);
            } else {
                t.right = new TreeNode(v);
                notFull.poll();
                notFull.offer(t.right);
            }
            return t.val;
        }

        public TreeNode get_root() {
            return this.root;
        }
    }

}

 解题思路:

注释写得很清楚

参考链接:

 力扣

上一篇:Shell文本处理三剑客之——sed编辑器


下一篇:IntelliJ IDEA 快捷键大全 Win 版