https://leetcode.com/problems/complete-binary-tree-inserter
Approach 1: Deque
X.
https://buptwc.com/2018/10/08/Leetcode-919-Complete-Binary-Tree-Inserter/
X. https://leetcode.com/problems/complete-binary-tree-inserter/discuss/178427/Java-BFS-straightforward-code-two-methods-Initialization-and-insert-time-O(1)-respectively.
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.
Write a data structure
CBTInserter
that is initialized with a complete binary tree and supports the following operations:CBTInserter(TreeNode root)
initializes the data structure on a given tree with head noderoot
;CBTInserter.insert(int v)
will insert aTreeNode
into the tree with valuenode.val = v
so that the tree remains complete, and returns the value of the parent of the insertedTreeNode
;CBTInserter.get_root()
will return the head node of the tree.
- The initial given tree is complete and contains between
1
and1000
nodes.
Approach 1: Deque
Consider all the nodes numbered first by level and then left to right. Call this the "number order" of the nodes.
At each insertion step, we want to insert into the node with the lowest number (that still has 0 or 1 children).
By maintaining a
deque
(double ended queue) of these nodes in number order, we can solve the problem. After inserting a node, that node now has the highest number and no children, so it goes at the end of the deque. To get the node with the lowest number, we pop from the beginning of the deque.
Algorithm
First, perform a breadth-first search to populate the
deque
with nodes that have 0 or 1 children, in number order.
Now when inserting a node, the parent is the first element of
deque
, and we add this new node to our deque
.- Time Complexity: The preprocessing is , where is the number of nodes in the tree. Each insertion operation thereafter is .
- Space Complexity: space complexity, when the size of the tree during the current insertion operation is .
TreeNode root;
Deque<TreeNode> deque;
public CBTInserter(TreeNode root) {
this.root = root;
deque = new LinkedList();
Queue<TreeNode> queue = new LinkedList();
queue.offer(root);
// BFS to populate deque
while (!queue.isEmpty()) {
TreeNode node = queue.poll();
if (node.left == null || node.right == null)
deque.offerLast(node);
if (node.left != null)
queue.offer(node.left);
if (node.right != null)
queue.offer(node.right);
}
}
public int insert(int v) {
TreeNode node = deque.peekFirst();
deque.offerLast(new TreeNode(v));
if (node.left == null)
node.left = deque.peekLast();
else {
node.right = deque.peekLast();
deque.pollFirst();
}
return node.val;
}
public TreeNode get_root() {
return root;
}
X.
https://buptwc.com/2018/10/08/Leetcode-919-Complete-Binary-Tree-Inserter/
一说到完全二叉树我们就要想到其最基本的特性,如果将根结点的序号定义为1的话,则对于任意一个结点i,他的左孩子序号为2*i,右孩子序号为2*i+1,想到这一步就可做了。
我们始终使用一个数组保存每个结点,数组的下标即代表结点的序号。对于给定的初始化树,我们使用bfs方法获得初始数组
https://leetcode.com/problems/complete-binary-tree-inserter/discuss/178424/C%2B%2BJavaPython-O(1)-Insert
Store tree nodes to a list
Node
self.tree
in bfs order.Node
tree[i]
has left child tree[2 * i + 1]
and tree[2 * i + 2]
So when insert the
we can find its parent
N
th node (0-indexed), we push it into the list.we can find its parent
tree[(N - 1) / 2]
directly. List<TreeNode> tree;
public CBTInserter(TreeNode root) {
tree = new ArrayList<>();
tree.add(root);
for (int i = 0; i < tree.size(); ++i) {
if (tree.get(i).left != null) tree.add(tree.get(i).left);
if (tree.get(i).right != null) tree.add(tree.get(i).right);
}
}
public int insert(int v) {
int N = tree.size();
TreeNode node = new TreeNode(v);
tree.add(node);
if (N % 2 == 1)
tree.get((N - 1) / 2).left = node;
else
tree.get((N - 1) / 2).right = node;
return tree.get((N - 1) / 2).val;
}
public TreeNode get_root() {
return tree.get(0);
}
X. https://leetcode.com/problems/complete-binary-tree-inserter/discuss/178427/Java-BFS-straightforward-code-two-methods-Initialization-and-insert-time-O(1)-respectively.
Init: O(n), insert(): O(1)
public CBTInserter(TreeNode root) {
this.root = root;
q.offer(root);
while (q.peek().left != null && q.peek().right != null) {
q.offer(q.peek().left);
q.offer(q.poll().right);
}
}
public int insert(int v) {
TreeNode p = q.peek();
if (p.left == null) {
p.left = new TreeNode(v);
}else {
p.right = new TreeNode(v);
q.offer(p.left);
q.offer(p.right);
q.poll();
}
return p.val;
}
public TreeNode get_root() { return root; }
Method 1:
Init: O(1), insert(): O(n)
Init: O(1), insert(): O(n)
private TreeNode root;
private Queue<TreeNode> q = new LinkedList<>();
public CBTInserter(TreeNode root) { this.root = root; }
public int insert(int v) {
q.offer(root);
while (true) {
TreeNode n = q.poll();
if (n.left != null && n.right != null) { // n has 2 children.
q.offer(n.left);
q.offer(n.right);
}else { // n has at most 1 child.
if (n.left == null) { n.left = new TreeNode(v); }
else { n.right = new TreeNode(v); }
return n.val;
}
}
}
public TreeNode get_root() { return root; }
X.
https://leetcode.com/problems/complete-binary-tree-inserter/discuss/178528/Java-Solution%3A-O(1)-Insert-VS.-O(1)-Pre-process-Trade-Off TreeNode root;
int size;
public CBTInserter(TreeNode root) {
this.root = root;
size = getSize(root);
//System.out.println(size);
}
int getSize(TreeNode root) {
if(root == null) return 0;
return getSize(root.left) + getSize(root.right) + 1;
}
int dfs(TreeNode node, int ind, int half, int v) {
if(ind >= half) {
if(node.right == null) {
node.right = new TreeNode(v);
return node.val;
}
return dfs(node.right, ind-half, half>>1, v);
}else {
if(node.left == null) {
node.left = new TreeNode(v);
return node.val;
}
return dfs(node.left, ind, half>>1, v);
}
}
public int insert(int v) {
++size;
int h = 1;
while(1<<h < size + 1) ++h;
//System.out.println(h);
int ind = size - (1<<(h-1));
//System.out.println(ind);
//System.out.println(1<<(h-2));
return dfs(root, ind, 1<<(h-2), v);
}
public TreeNode get_root() {
return this.root;
}
}
2. O(1) Build Tree + O(N) Insert:
private TreeNode root;
public CBTInserter(TreeNode root) {
this.root = root;
}
public int insert(int v) {
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
TreeNode cur = queue.poll();
if (cur.left != null) {
queue.offer(cur.left);
} else {
cur.left = new TreeNode(v);
return cur.val;
}
if (cur.right != null) {
queue.offer(cur.right);
} else {
cur.right = new TreeNode(v);
return cur.val;
}
}
return 0;
}
public TreeNode get_root() {
return root;
}