树
广度优先搜索
设计
二叉树
题目描述
完全二叉树 是每一层(除最后一层外)都是完全填充(即,节点数达到最大)的,并且所有的节点都尽可能地集中在左侧。
设计一种算法,将一个新节点插入到一棵完全二叉树中,并在插入后保持其完整。
实现 CBTInserter
类:
CBTInserter(TreeNode root)
使用头节点为 root
的给定树初始化该数据结构;
CBTInserter.insert(int v)
向树中插入一个值为 Node.val == val
的新节点 TreeNode
。使树保持完全二叉树的状态,并返回插入节点 TreeNode
的父节点的值 ;
CBTInserter.get_root()
将返回树的头节点。
示例 1:
输入
["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]
提示:
树中节点数量范围为 [1, 1000]
0 <= Node.val <= 5000
root
是完全二叉树
0 <= val <= 5000
每个测试用例最多调用 insert
和 get_root
操作 104
次
解法
方法一:BFS
我们可以使用一个数组 $tree$ 来存储完全二叉树的所有节点。在初始化时,我们使用一个队列 $q$ 来层序遍历给定的树,并将所有节点存储到数组 $tree$ 中。
在插入节点时,我们可以通过数组 $tree$ 来找到新节点的父节点 $p$。然后我们创建一个新节点 $node$,将其插入到数组 $tree$ 中,并将 $node$ 作为 $p$ 的左子节点或右子节点。最后返回 $p$ 的值。
在获取根节点时,我们直接返回数组 $tree$ 的第一个元素。
时间复杂度方面,初始化时需要 $O(n)$ 的时间,插入节点和获取根节点的时间复杂度均为 $O(1)$。空间复杂度为 $O(n)$。其中 $n$ 为树中节点的数量。
Python3 Java C++ Go TypeScript JavaScript
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 # Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class CBTInserter :
def __init__ ( self , root : Optional [ TreeNode ]):
self . tree = []
q = deque ([ root ])
while q :
for _ in range ( len ( q )):
node = q . popleft ()
self . tree . append ( node )
if node . left :
q . append ( node . left )
if node . right :
q . append ( node . right )
def insert ( self , val : int ) -> int :
p = self . tree [( len ( self . tree ) - 1 ) // 2 ]
node = TreeNode ( val )
self . tree . append ( node )
if p . left is None :
p . left = node
else :
p . right = node
return p . val
def get_root ( self ) -> Optional [ TreeNode ]:
return self . tree [ 0 ]
# Your CBTInserter object will be instantiated and called as such:
# obj = CBTInserter(root)
# param_1 = obj.insert(val)
# param_2 = obj.get_root()
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
50
51
52
53
54
55
56
57
58 /**
* Definition for a binary tree node.
* 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 {
private List < TreeNode > tree = new ArrayList <> ();
public CBTInserter ( TreeNode root ) {
Deque < TreeNode > q = new ArrayDeque <> ();
q . offer ( root );
while ( ! q . isEmpty ()) {
for ( int i = q . size (); i > 0 ; -- i ) {
TreeNode node = q . poll ();
tree . add ( node );
if ( node . left != null ) {
q . offer ( node . left );
}
if ( node . right != null ) {
q . offer ( node . right );
}
}
}
}
public int insert ( int val ) {
TreeNode p = tree . get (( tree . size () - 1 ) / 2 );
TreeNode node = new TreeNode ( val );
tree . add ( node );
if ( p . left == null ) {
p . left = node ;
} else {
p . right = node ;
}
return p . val ;
}
public TreeNode get_root () {
return tree . get ( 0 );
}
}
/**
* Your CBTInserter object will be instantiated and called as such:
* CBTInserter obj = new CBTInserter(root);
* int param_1 = obj.insert(val);
* TreeNode param_2 = obj.get_root();
*/
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
50
51
52
53
54
55
56 /**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class CBTInserter {
public :
CBTInserter ( TreeNode * root ) {
queue < TreeNode *> q {{ root }};
while ( q . size ()) {
for ( int i = q . size (); i ; -- i ) {
auto node = q . front ();
q . pop ();
tree . push_back ( node );
if ( node -> left ) {
q . push ( node -> left );
}
if ( node -> right ) {
q . push ( node -> right );
}
}
}
}
int insert ( int val ) {
auto p = tree [( tree . size () - 1 ) / 2 ];
auto node = new TreeNode ( val );
tree . push_back ( node );
if ( ! p -> left ) {
p -> left = node ;
} else {
p -> right = node ;
}
return p -> val ;
}
TreeNode * get_root () {
return tree [ 0 ];
}
private :
vector < TreeNode *> tree ;
};
/**
* Your CBTInserter object will be instantiated and called as such:
* CBTInserter* obj = new CBTInserter(root);
* int param_1 = obj->insert(val);
* TreeNode* param_2 = obj->get_root();
*/
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
50
51
52
53 /**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
type CBTInserter struct {
tree [] * TreeNode
}
func Constructor ( root * TreeNode ) CBTInserter {
q := [] * TreeNode { root }
tree := [] * TreeNode {}
for len ( q ) > 0 {
for i := len ( q ); i > 0 ; i -- {
node := q [ 0 ]
q = q [ 1 :]
tree = append ( tree , node )
if node . Left != nil {
q = append ( q , node . Left )
}
if node . Right != nil {
q = append ( q , node . Right )
}
}
}
return CBTInserter { tree }
}
func ( this * CBTInserter ) Insert ( val int ) int {
p := this . tree [( len ( this . tree ) - 1 ) / 2 ]
node := & TreeNode { val , nil , nil }
this . tree = append ( this . tree , node )
if p . Left == nil {
p . Left = node
} else {
p . Right = node
}
return p . Val
}
func ( this * CBTInserter ) Get_root () * TreeNode {
return this . tree [ 0 ]
}
/**
* Your CBTInserter object will be instantiated and called as such:
* obj := Constructor(root);
* param_1 := obj.Insert(val);
* param_2 := obj.Get_root();
*/
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
50
51
52
53
54
55
56 /**
* Definition for a binary tree node.
* class TreeNode {
* val: number
* left: TreeNode | null
* right: TreeNode | null
* constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
* }
*/
class CBTInserter {
private tree : TreeNode [] = [];
constructor ( root : TreeNode | null ) {
if ( root === null ) {
return ;
}
const q : TreeNode [] = [ root ];
while ( q . length ) {
const t : TreeNode [] = [];
for ( const node of q ) {
this . tree . push ( node );
node . left !== null && t . push ( node . left );
node . right !== null && t . push ( node . right );
}
q . splice ( 0 , q . length , ... t );
}
}
insert ( val : number ) : number {
const p = this . tree [( this . tree . length - 1 ) >> 1 ];
const node = new TreeNode ( val );
this . tree . push ( node );
if ( p . left === null ) {
p . left = node ;
} else {
p . right = node ;
}
return p . val ;
}
get_root () : TreeNode | null {
return this . tree [ 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()
*/
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
50
51
52
53
54
55
56
57 /**
* 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 . tree = [];
if ( root === null ) {
return ;
}
const q = [ root ];
while ( q . length ) {
const t = [];
for ( const node of q ) {
this . tree . push ( node );
node . left !== null && t . push ( node . left );
node . right !== null && t . push ( node . right );
}
q . splice ( 0 , q . length , ... t );
}
};
/**
* @param {number} val
* @return {number}
*/
CBTInserter . prototype . insert = function ( val ) {
const p = this . tree [( this . tree . length - 1 ) >> 1 ];
const node = new TreeNode ( val );
this . tree . push ( node );
if ( p . left === null ) {
p . left = node ;
} else {
p . right = node ;
}
return p . val ;
};
/**
* @return {TreeNode}
*/
CBTInserter . prototype . get_root = function () {
return this . tree [ 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()
*/
GitHub