Skip to content

Commit 3876498

Browse files
authored
Create README.md
1 parent 7f1f613 commit 3876498

File tree

1 file changed

+333
-0
lines changed
  • 17 - Binary Tree Data Structure Problems/33 - Amount of Time for BInary Tree to Be Infected

1 file changed

+333
-0
lines changed
Lines changed: 333 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,333 @@
1+
<h1 align='center'>Amount - of Time - For Binary - To be - Infected</h1>
2+
3+
## Problem Statement
4+
5+
**Problem URL :** [Amount of Time for Binary To be Infected](https://leetcode.com/problems/amount-of-time-for-binary-tree-to-be-infected/)
6+
7+
![image](https://github.com/user-attachments/assets/048159f7-4c71-4dd4-8310-1fa7aebdcaac)
8+
![image](https://github.com/user-attachments/assets/803844ce-33f2-4fab-8172-94a168f1d3b9)
9+
10+
## Problem Explanation
11+
The problem is titled **"Amount of Time for Binary Tree to be Infected"** on LeetCode. Given a binary tree where each node has a unique integer value, we select a `start` node, which becomes infected at time 0. The infection spreads to all directly connected nodes (left child, right child, and parent node) each minute. We need to determine the total time required for the entire tree to be infected.
12+
13+
### Constraints
14+
- Nodes are only infected if connected to an already infected node.
15+
- You are given the `start` node's value, which initiates the infection.
16+
17+
### Example
18+
Imagine the binary tree:
19+
```
20+
1
21+
/ \
22+
2 3
23+
/ \
24+
4 5
25+
```
26+
If we start at node `2`, the infection spreads like this:
27+
1. **Minute 0**: Node 2 is infected.
28+
2. **Minute 1**: Nodes 1 and 4 (connected to node 2) are infected.
29+
3. **Minute 2**: Nodes 3 and 5 become infected.
30+
31+
The entire tree is infected in **2 minutes**.
32+
33+
### Edge Cases
34+
- If the tree has only one node, it’s already infected at minute 0.
35+
- If the `start` node is a leaf node, the infection needs more time to spread upward to the root and then to other branches.
36+
37+
## Step 2: Approach
38+
39+
### High-Level Overview
40+
1. First, find the `start` node in the binary tree.
41+
2. Track each node’s parent using a map for easy access to all adjacent nodes.
42+
3. Perform a level-order traversal (BFS) from the `start` node to spread the infection. Keep track of infected nodes to avoid re-infecting nodes.
43+
44+
### Step-by-Step Breakdown
45+
1. **Identify the Start Node**: Traverse the tree to find the `start` node and build a map that links each node to its parent.
46+
2. **Infection Spread Simulation**: Using a BFS from the `start` node, simulate the infection spread minute-by-minute by visiting all uninfected neighboring nodes.
47+
3. **Count the Time**: For each level in BFS, increment the time until no uninfected nodes remain.
48+
49+
### Pseudocode
50+
1. Traverse the tree to find the start node and populate the parent map.
51+
2. Initiate BFS from the start node, marking each visited node as infected.
52+
3. For each level, count the minutes until all nodes are infected.
53+
54+
## Problem Solution
55+
```cpp
56+
/**
57+
* Definition for a binary tree node.
58+
* struct TreeNode {
59+
* int val;
60+
* TreeNode *left;
61+
* TreeNode *right;
62+
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
63+
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
64+
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
65+
* };
66+
*/
67+
class Solution {
68+
public:
69+
TreeNode* startPoint(TreeNode* root, int start, unordered_map<TreeNode*, TreeNode*> &childParentMapping){
70+
TreeNode* result = NULL;
71+
queue<TreeNode*> q;
72+
q.push(root);
73+
74+
childParentMapping[root] = NULL;
75+
76+
while(!q.empty()){
77+
TreeNode* front = q.front();
78+
q.pop();
79+
80+
if(front -> val == start){
81+
result = front;
82+
}
83+
84+
if(front -> left){
85+
childParentMapping[front -> left] = front;
86+
q.push(front -> left);
87+
}
88+
89+
if(front -> right){
90+
childParentMapping[front -> right] = front;
91+
q.push(front -> right);
92+
}
93+
}
94+
95+
return result;
96+
}
97+
98+
int t_infected_time(TreeNode* root, unordered_map<TreeNode*, TreeNode*> childParentMapping){
99+
int minutes = -1;
100+
101+
unordered_map<TreeNode*, bool> infected;
102+
queue<TreeNode*> q;
103+
104+
q.push(root);
105+
106+
infected[root] = true;
107+
108+
while(!q.empty()){
109+
int size = q.size();
110+
bool flag = true;
111+
112+
for(int i = 0; i < size; i++){
113+
114+
TreeNode* front = q.front();
115+
q.pop();
116+
117+
if(front -> left && !infected[front -> left]){
118+
flag = true;
119+
q.push(front -> left);
120+
infected[front -> left] = true;
121+
}
122+
123+
if(front -> right && !infected[front -> right]){
124+
flag = true;
125+
q.push(front -> right);
126+
infected[front -> right] = true;
127+
}
128+
129+
if(childParentMapping[front] && !infected[childParentMapping[front]]){
130+
flag = true;
131+
q.push(childParentMapping[front]);
132+
infected[childParentMapping[front]] = true;
133+
}
134+
}
135+
136+
if(flag == true) minutes++;
137+
}
138+
139+
return minutes;
140+
}
141+
int amountOfTime(TreeNode* root, int start) {
142+
unordered_map<TreeNode*, TreeNode*> childParentMapping;
143+
TreeNode* startNode = startPoint(root, start, childParentMapping);
144+
return t_infected_time(startNode, childParentMapping);
145+
}
146+
};
147+
```
148+
149+
## Problem Solution Explanation
150+
151+
```cpp
152+
/**
153+
* Definition for a binary tree node.
154+
* struct TreeNode {
155+
* int val;
156+
* TreeNode *left;
157+
* TreeNode *right;
158+
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
159+
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
160+
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
161+
* };
162+
*/
163+
class Solution {
164+
```
165+
166+
This part sets up the `TreeNode` structure, representing each node in the binary tree, with `val` holding the node's value, and `left` and `right` pointers representing child nodes. It defines three constructors:
167+
1. **Default Constructor**: Creates a node with `val = 0`.
168+
2. **Parameterized Constructor**: Creates a node with a given `val`.
169+
3. **Complete Constructor**: Creates a node with a given `val`, `left`, and `right`.
170+
171+
172+
### Function 1: `startPoint`
173+
174+
This function finds the `start` node in the tree and builds a map linking each child node to its parent for easy traversal.
175+
176+
```cpp
177+
TreeNode* startPoint(TreeNode* root, int start, unordered_map<TreeNode*, TreeNode*> &childParentMapping) {
178+
TreeNode* result = NULL; // Holds the start node reference
179+
queue<TreeNode*> q; // Queue for level-order traversal
180+
q.push(root);
181+
182+
childParentMapping[root] = NULL; // Root has no parent
183+
184+
while (!q.empty()) {
185+
TreeNode* front = q.front();
186+
q.pop();
187+
188+
if (front->val == start) { // Check if we found the start node
189+
result = front;
190+
}
191+
192+
if (front->left) { // Map left child to its parent
193+
childParentMapping[front->left] = front;
194+
q.push(front->left);
195+
}
196+
197+
if (front->right) { // Map right child to its parent
198+
childParentMapping[front->right] = front;
199+
q.push(front->right);
200+
}
201+
}
202+
203+
return result; // Return the start node
204+
}
205+
```
206+
207+
#### Example 1: Basic Tree
208+
209+
Consider this tree and suppose `start = 2`:
210+
211+
```
212+
1
213+
/ \
214+
2 3
215+
/ \
216+
4 5
217+
```
218+
219+
1. **Queue Initialization**: `q = [1]`
220+
2. **Map Creation**: `childParentMapping = {1: NULL}`
221+
3. **Node 1 Processing**:
222+
- Set `2`’s parent to `1`: `childParentMapping = {1: NULL, 2: 1}`
223+
- Set `3`’s parent to `1`: `childParentMapping = {1: NULL, 2: 1, 3: 1}`
224+
- `q = [2, 3]`
225+
4. **Node 2 Processing**:
226+
- `start` node found, so `result = 2`
227+
- Set `4`’s parent to `2`: `childParentMapping = {1: NULL, 2: 1, 3: 1, 4: 2}`
228+
- Set `5`’s parent to `2`: `childParentMapping = {1: NULL, 2: 1, 3: 1, 4: 2, 5: 2}`
229+
- `q = [3, 4, 5]`
230+
5. **Final Output**: `result = 2`
231+
232+
This completes the map of each node to its parent and identifies `2` as the starting node.
233+
234+
235+
### Function 2: `t_infected_time`
236+
237+
This function calculates the total time required to infect the entire tree, starting from the given node. It uses a breadth-first search (BFS) to spread the infection level by level.
238+
239+
```cpp
240+
int t_infected_time(TreeNode* root, unordered_map<TreeNode*, TreeNode*> childParentMapping) {
241+
int minutes = -1; // Infection time counter
242+
unordered_map<TreeNode*, bool> infected; // Track infected nodes
243+
queue<TreeNode*> q;
244+
245+
q.push(root); // Start from the root node
246+
infected[root] = true;
247+
248+
while (!q.empty()) {
249+
int size = q.size(); // Number of nodes in the current level
250+
bool flag = false; // Track if new nodes are infected this minute
251+
252+
for (int i = 0; i < size; i++) {
253+
TreeNode* front = q.front();
254+
q.pop();
255+
256+
// Check left child
257+
if (front->left && !infected[front->left]) {
258+
flag = true;
259+
q.push(front->left);
260+
infected[front->left] = true;
261+
}
262+
263+
// Check right child
264+
if (front->right && !infected[front->right]) {
265+
flag = true;
266+
q.push(front->right);
267+
infected[front->right] = true;
268+
}
269+
270+
// Check parent
271+
if (childParentMapping[front] && !infected[childParentMapping[front]]) {
272+
flag = true;
273+
q.push(childParentMapping[front]);
274+
infected[childParentMapping[front]] = true;
275+
}
276+
}
277+
278+
if (flag) minutes++; // Increment if any new infections occurred
279+
}
280+
281+
return minutes;
282+
}
283+
```
284+
285+
#### Example 2: Infection Spread
286+
287+
Using the previous tree with `start = 2`, let’s see how the infection spreads:
288+
289+
1. **Minute 0**: Node `2` is infected (`q = [2]`)
290+
2. **Minute 1**:
291+
- Infect nodes `1` and `4`: `q = [1, 4]`
292+
3. **Minute 2**:
293+
- Infect nodes `3` and `5`: `q = [3, 5]`
294+
4. **Result**: The tree is fully infected in **2 minutes**.
295+
296+
### Final Function: `amountOfTime`
297+
298+
This function ties everything together by calling `startPoint` to find the start node and `t_infected_time` to calculate the time to infect the tree.
299+
300+
```cpp
301+
int amountOfTime(TreeNode* root, int start) {
302+
unordered_map<TreeNode*, TreeNode*> childParentMapping;
303+
TreeNode* startNode = startPoint(root, start, childParentMapping);
304+
return t_infected_time(startNode, childParentMapping);
305+
}
306+
```
307+
308+
1. **Example**: For the tree above, `amountOfTime(root, 2)` returns `2` minutes.
309+
310+
### Step 4: Additional Examples
311+
312+
1. **Single Node Tree**: Tree with one node (start = 1).
313+
- **Input**: `root = [1]`, `start = 1`
314+
- **Output**: `0` minutes (tree is infected immediately).
315+
316+
2. **Skewed Tree** (like a linked list):
317+
```
318+
1
319+
\
320+
2
321+
\
322+
3
323+
\
324+
4
325+
```
326+
- **Input**: `root = [1, null, 2, null, 3, null, 4]`, `start = 1`
327+
- **Output**: `3` minutes (infection moves one node per minute down the chain).
328+
329+
330+
### Step 5: Time and Space Complexity Analysis
331+
332+
- **Time Complexity**: \(O(n)\), where \(n\) is the number of nodes in the tree. Each node is visited once during `startPoint` and `t_infected_time`.
333+
- **Space Complexity**: \(O(n)\) for the parent map, infected map, and queue.

0 commit comments

Comments
 (0)