919 Complete Binary Tree Inserter 完全二叉樹插入器
Description:
A complete binary tree is a binary tree in which every level, except possibly the last, is completely filled, and all nodes are as far left as possible.
Design an algorithm to insert a new node to a complete binary tree keeping it complete after the insertion.
Implement the CBTInserter class:
CBTInserter(TreeNode root) Initializes the data structure with the root of the complete binary tree.
int insert(int v) Inserts a TreeNode into the tree with value Node.val == val so that the tree remains complete, and returns the value of the parent of the inserted TreeNode.
TreeNode get_root() Returns the root node of the tree.
Example:
Example 1:
Input
["CBTInserter", "insert", "insert", "get_root"]
[[[1, 2]], [3], [4], []]
Output
[null, 1, 2, [1, 2, 3, 4]]
Explanation
CBTInserter cBTInserter = new CBTInserter([1, 2]);
cBTInserter.insert(3); // return 1
cBTInserter.insert(4); // return 2
cBTInserter.get_root(); // return [1, 2, 3, 4]
Constraints:
The number of nodes in the tree will be in the range [1, 1000].
0 <= Node.val <= 5000
root is a complete binary tree.
0 <= val <= 5000
At most 10^4 calls will be made to insert and get_root.
題目描述:
完全二叉樹是每一層(除最後一層外)都是完全填充(即,節點數達到最大)的,並且所有的節點都儘可能地集中在左側。
設計一個用完全二叉樹初始化的數據結構 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 之間。
思路:
層序遍歷
初始化時按照層序遍歷加入等待隊列
左右子樹有空的需要在等待隊列中等待插入
左右子樹都非空的彈出等待隊列
插入時先插入左子樹, 右子樹插入時即滿足兩個子樹都非空將這個結點從等待隊列中彈出
時間複雜度爲 O(n), 空間複雜度爲 O(1)
代碼:
C++:
/**
* 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
{
private:
TreeNode* root;
queue<TreeNode*> data;
public:
CBTInserter(TreeNode* root)
{
this -> root = root;
queue<TreeNode*> q;
q.push(root);
while (!q.empty())
{
TreeNode* cur = q.front();
q.pop();
if (!cur -> left or !cur -> right) data.push(cur);
if (cur -> left) q.push(cur -> left);
if (cur -> right) q.push(cur -> right);
}
}
int insert(int val)
{
TreeNode* cur = data.front();
if (!cur -> left)
{
cur -> left = new TreeNode(val);
data.push(cur -> left);
} else {
cur -> right = new TreeNode(val);
data.pop();
data.push(cur -> right);
}
return cur -> val;
}
TreeNode* get_root()
{
return root;
}
};
/**
* 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();
*/
Java:
/**
* 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 Queue<TreeNode> data;
private TreeNode root;
public CBTInserter(TreeNode root) {
this.root = root;
this.data = new LinkedList<>();
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
TreeNode cur = queue.poll();
if (cur.left == null || cur.right == null) this.data.offer(cur);
if (cur.left != null) queue.offer(cur.left);
if (cur.right != null) queue.offer(cur.right);
}
}
public int insert(int val) {
TreeNode cur = this.data.peek();
if (cur.left == null) {
cur.left = new TreeNode(val);
this.data.offer(cur.left);
} else {
cur.right = new TreeNode(val);
this.data.poll();
this.data.offer(cur.right);
}
return cur.val;
}
public TreeNode get_root() {
return this.root;
}
}
/**
* 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();
*/
Python:
# 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: TreeNode):
self.root = root
self.data = deque()
q = deque([root])
while q:
(((x := q.popleft()).left is None or x.right is None) and self.data.append(x)) or (x.left and q.append(x.left)) or (x.right and q.append(x.right))
def insert(self, val: int) -> int:
x = self.data[0]
if x.left is None:
x.left = TreeNode(val)
self.data.append(x.left)
else:
x.right = TreeNode(val)
self.data.popleft()
self.data.append(x.right)
return x.val
def get_root(self) -> TreeNode:
return self.root
# Your CBTInserter object will be instantiated and called as such:
# obj = CBTInserter(root)
# param_1 = obj.insert(val)
# param_2 = obj.get_root()