Skip to main content

完全二叉树插入器

题目

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

设计一种算法, 将一个新节点插入到一个完整的二叉树中, 并在插入后保持其完整.

实现 CBTInserter 类:

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

说明:

  • 树中节点数量范围为 [1, 1000]
  • 0 <= Node.val <= 5000
  • root 是完全二叉树
  • 0 <= val <= 5000
  • 每个测试用例最多调用 insertget_root 操作 104
示例
输入:
["CBTInserter", "insert", "insert", "get_root"]
[[[1, 2]], [3], [4], []]

输出:
[null, 1, 2, [1, 2, 3, 4]]

解释:
CBTInserter cBTInserter = new CBTInserter([1, 2]);
cBTInserter.insert(3); // 返回 1
cBTInserter.insert(4); // 返回 2
cBTInserter.get_root(); // 返回 [1, 2, 3, 4]

919-cbt-inserter

题解

对于一棵完全二叉树而言, 除了最后一层之外的其他每一层都被完全填充, 并且所有结点都保持向左对齐.

对于 insert 操作而言, 我们要在数组(层序遍历顺序)中找到首个存在左右空子节点的父节点 father, 由于找到 father 节点的过程数组下标单调递增, 因此可以使用全局变量 idx 不断往后搜索, 每次将新节点 node 添加到当前树后, 需要将 node 也添加到数组尾部.

/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
*/
var CBTInserter = function (root) {
this.list = []
this.idx = 0
const queue = [root]

while (queue.length !== 0) {
const n = queue.length

for (let i = 0; i < n; i++) {
const node = queue.shift()
this.list.push(node)

if (node.left) queue.push(node.left)
if (node.right) queue.push(node.right)
}
}
}

/**
* @param {number} val
* @return {number}
*/
CBTInserter.prototype.insert = function (val) {
const node = new TreeNode(val)
while (
this.list[this.idx].left !== null &&
this.list[this.idx].right !== null
) {
this.idx++
}

const father = this.list[this.idx]
if (father.left === null) {
father.left = node
} else if (father.right == null) {
father.right = node
}

this.list.push(node)
return father.val
}

/**
* @return {TreeNode}
*/
CBTInserter.prototype.get_root = function () {
return this.list[0]
}

/**
* Your CBTInserter object will be instantiated and called as such:
* var obj = new CBTInserter(root)
* var param_1 = obj.insert(val)
* var param_2 = obj.get_root()
*/