Back to Trees And Trie
Add One Row to Tree
Add One Row to Tree
🧩 Problem Statement
Given the root of a binary tree and two integers val and depth:
- Add a row of nodes with value
valat the givendepth. - The root node is at depth 1.
Rules: - If
depth == 1, create a new root with valueval, and the original tree becomes the new root's left subtree. - If
depth > 1, for each non-null node atdepth - 1(let's call itcur): - Create two nodes with value
val. cur.leftbecomes the left child of the new left node.cur.rightbecomes the right child of the new right node.- The new left node becomes
cur.left. - The new right node becomes
cur.right.
🔹 Example 1:
Input:
root = [4,2,6,3,1,5], val = 1, depth = 2
Output:
[4,1,1,2,null,null,6,3,1,5]
🔍 Approaches
1. BFS / Level Order Traversal ($O(N)$)
- Concept: Traverse to
depth - 1. Perform the pointer rewiring. - Algorithm:
- If
depth == 1: New root. - Queue
q. Pushroot. - Traverse
depth - 2levels (to arrive at leveldepth - 1). - For all nodes at this level:
tempLeft = node.lefttempRight = node.rightnode.left = new Node(val)node.right = new Node(val)node.left.left = tempLeftnode.right.right = tempRight
⏳ Time & Space Complexity
- Time Complexity: $O(N)$. Worst case we traverse the whole tree.
- Space Complexity: $O(N)$ (Queue width).
🚀 Code Implementations
C++
#include <vector>
#include <queue>
#include <iostream>
using namespace std;
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 Solution {
public:
TreeNode* addOneRow(TreeNode* root, int val, int depth) {
if (depth == 1) {
TreeNode* newRoot = new TreeNode(val);
newRoot->left = root;
return newRoot;
}
queue<TreeNode*> q;
q.push(root);
int currentDepth = 1;
while (!q.empty()) {
int size = q.size();
// If we are at the parent level (depth - 1)
if (currentDepth == depth - 1) {
for (int i = 0; i < size; i++) {
TreeNode* node = q.front(); q.pop();
TreeNode* oldLeft = node->left;
TreeNode* oldRight = node->right;
node->left = new TreeNode(val);
node->right = new TreeNode(val);
node->left->left = oldLeft;
node->right->right = oldRight;
}
break; // Done
}
for (int i = 0; i < size; i++) {
TreeNode* node = q.front(); q.pop();
if (node->left) q.push(node->left);
if (node->right) q.push(node->right);
}
currentDepth++;
}
return root;
}
};
Python
from typing import Optional
from collections import deque
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
class Solution:
def addOneRow(self, root: Optional[TreeNode], val: int, depth: int) -> Optional[TreeNode]:
if depth == 1:
return TreeNode(val, left=root)
queue = deque([root])
current_depth = 1
while queue:
if current_depth == depth - 1:
for _ in range(len(queue)):
node = queue.popleft()
old_left = node.left
old_right = node.right
node.left = TreeNode(val, left=old_left)
node.right = TreeNode(val, right=old_right)
break
for _ in range(len(queue)):
node = queue.popleft()
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
current_depth += 1
return root
Java
import java.util.*;
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 Solution {
public TreeNode addOneRow(TreeNode root, int val, int depth) {
if (depth == 1) {
TreeNode newRoot = new TreeNode(val);
newRoot.left = root;
return newRoot;
}
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
int currentDepth = 1;
while (!queue.isEmpty()) {
int size = queue.size();
if (currentDepth == depth - 1) {
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();
TreeNode oldLeft = node.left;
TreeNode oldRight = node.right;
node.left = new TreeNode(val);
node.left.left = oldLeft;
node.right = new TreeNode(val);
node.right.right = oldRight;
}
break;
}
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();
if (node.left != null) queue.offer(node.left);
if (node.right != null) queue.offer(node.right);
}
currentDepth++;
}
return root;
}
}
🌍 Real-World Analogy
Renovating a Building:
You want to add a new floor between the 1st and 2nd floor. You jack up the 2nd floor and everything above it, insert the new floor, and connect the stairs.
🎯 Summary
✅ Pointer Rewiring: The core logic handles preserving the existing subtrees by attaching them to the newly created nodes.
Solution Code
O(n) TimeO(1) Space
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
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 Solution {
public:
TreeNode *addOneRow(TreeNode *root, int val, int depth) {
if (depth == 1) {
TreeNode *newRoot = new TreeNode(val);
newRoot->left = root;
return newRoot;
}
queue<TreeNode *> q;
q.push(root);
int currentDepth = 1;
while (!q.empty()) {
int size = q.size();
// If we are at the parent level (depth - 1)
if (currentDepth == depth - 1) {
for (int i = 0; i < size; i++) {
TreeNode *node = q.front();
q.pop();
TreeNode *oldLeft = node->left;
TreeNode *oldRight = node->right;
node->left = new TreeNode(val);
node->right = new TreeNode(val);
node->left->left = oldLeft;
node->right->right = oldRight;
}
break; // Done
}
for (int i = 0; i < size; i++) {
TreeNode *node = q.front();
q.pop();
if (node->left)
q.push(node->left);
if (node->right)
q.push(node->right);
}
currentDepth++;
}
return root;
}
};
void levelOrder(TreeNode *root) {
if (!root)
return;
queue<TreeNode *> q;
q.push(root);
cout << "[";
while (!q.empty()) {
TreeNode *curr = q.front();
q.pop();
if (curr) {
cout << curr->val << ",";
q.push(curr->left);
q.push(curr->right);
} else {
cout << "null,";
}
}
cout << "]" << endl;
}
int main() {
Solution sol;
// [4,2,6,3,1,5], val = 1, depth = 2
TreeNode *root = new TreeNode(4);
root->left = new TreeNode(2);
root->right = new TreeNode(6);
root->left->left = new TreeNode(3);
root->left->right = new TreeNode(1);
root->right->left = new TreeNode(5);
TreeNode *res = sol.addOneRow(root, 1, 2);
cout << "Test Case 1: ";
// Expected level order conceptually: [4,1,1,2,null,null,6,3,1,5]
// 4 -> left:1, right:1
// left:1 -> left:2
// right:1 -> right:6
if (res->val == 4 && res->left->val == 1 && res->right->val == 1 &&
res->left->left->val == 2) {
cout << "Verified (4 -> 1,1 -> 2 ...)" << endl;
} else {
cout << "Failed" << endl;
}
return 0;
}
SYSTEM STABLEUTF-8 • STATIC_RENDER