题目名称

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

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

实现 CBTInserter 类:

CBTInserter(TreeNode root) 使用头节点为 root 的给定树初始化该数据结构;

CBTInserter.insert(int v) 向树中插入一个值为 Node.val == val的新节点 TreeNode。使树保持完全二叉树的状态,并返回插入节点 TreeNode 的父节点的值;

CBTInserter.get_root() 将返回树的头节点。

示例

输入
[“CBTInserter”, “insert”, “insert”, “get_root”]
[[[1, 2]], [3], [4], []]

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

题解

这道题主要考察树的 广度优先遍历(bfs)

我们需要从树中取出非完全二叉树的节点,所以最重要的就是如何取出这个节点,这里采用的是 广度优先遍历的方法,首先将树根据节点顺序转化成为一个数组,然后在数组中找出第一个不完全二叉树节点

但是目前由于需要操作的步骤过多,性能较差,有待优化

答案

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
var CBTInserter = function(root) {
this.root = root
this.incompleteNode = getFirstIncompleteTree(root)
};

CBTInserter.prototype.insert = function(val) {
if(!this.incompleteNode.left) {
this.incompleteNode.left = {
val: val
}
} else if(!this.incompleteNode.right) {
this.incompleteNode.right = {
val: val
}
}
let parent = this.incompleteNode
if(this.incompleteNode.left && this.incompleteNode.right) {
this.incompleteNode = getFirstIncompleteTree(this.root)
}
return parent.val
};

function getFirstIncompleteTree(root) {
let nodeList = getTreeNodes([root])
for(let i = 0; i < nodeList.length; i++) {
let node = checkIncompleteTree(nodeList[i])
if(node) return nodeList[i]
}
return null
}

function getTreeNodes(arr = [root]) {
let newArr = [...arr]
for(let i = 0; i < arr.length; i++) {
let root = arr[i]
root.left && newArr.push(root.left)
root.right && newArr.push(root.right)
if(!root.left || !root.right) return newArr
}
return getTreeNodes(newArr)
}

function checkIncompleteTree(node) {
return !node.left || !node.right
}

CBTInserter.prototype.get_root = function() {
return this.root
};