题目
完全二叉树 是每一层(除最后一层外)都是完全填充(即,节点数达到最大)的,并且所有的节点都尽可能地集中在左侧。
设计一种算法,将一个新节点插入到一个完整的二叉树中,并在插入后保持其完整。
实现 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 次
思路
- 使用队列模拟,遍历二叉树的所有节点,发现左孩子或者右孩子为空的节点即记录,标记该节点。就是代码中get_temp()方法
- 初始化:记录根节点,以便get_root()方法直接返回, 调用get_temp()方法获得首个标记节点
- 将给定值插入到标记节点中,并重置该标记节点即可
题解
from collections import deque
class CBTInserter:
# 初始化
def __init__(self, root: TreeNode):
self.root = root
self.temp = self.get_temp(root)
def insert(self, val: int) -> int:
# 构造子节点,插入到标记节点中
if self.temp.left:
self.temp.right = TreeNode(val)
else:
self.temp.left = TreeNode(val)
# 记录标记节点的值,在后面返回
value = self.temp.val
# 重置标记节点
self.temp = self.get_temp(self.root)
return value
def get_root(self) -> TreeNode:
return self.root
# 寻找子节点为空的节点
def get_temp(self, root):
# 队列
res = deque()
res.append(root)
while res:
index = res.popleft()
if index.left:
res.append(index.left)
# 左孩子为空,直接返回该节点
else:
return index
if index.right:
res.append(index.right)
# 右孩子为空,直接返回该节点
else:
return index
return None