Skip to content

Commit e71dead

Browse files
authored
Create README.md
1 parent 2b743c9 commit e71dead

File tree

1 file changed

+282
-0
lines changed
  • 17 - Binary Tree Data Structure Problems/35 - Flatten Binary Tree to Linked List

1 file changed

+282
-0
lines changed
Lines changed: 282 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,282 @@
1+
<h1 align='center'>Flatten - Binary - Tree - to - Linked - List</h1>
2+
3+
## Problem Statement
4+
5+
**Problem URL :** [Flatten Binary Tree to Linked List](https://leetcode.com/problems/flatten-binary-tree-to-linked-list/)
6+
7+
![image](https://github.com/user-attachments/assets/e1dded1d-42ce-406f-905e-fa3e449d0195)
8+
![image](https://github.com/user-attachments/assets/bacc21f4-ffef-49a1-9cc6-7ff61da5ced5)
9+
10+
## Problem Explanation
11+
12+
**Problem**: Given the root of a binary tree, the task is to flatten the tree into a linked list **in-place**. The flattened tree should follow the structure of a pre-order traversal, where each node's left child is null and the right child points to the next node in the traversal order.
13+
14+
**Constraints**:
15+
1. Do not use extra space for a new data structure.
16+
2. Transform the tree in-place without affecting the original node values.
17+
18+
**Example**:
19+
Suppose we have the following binary tree:
20+
21+
```
22+
1
23+
/ \
24+
2 5
25+
/ \ \
26+
3 4 6
27+
```
28+
29+
The flattened linked list representation should look like this:
30+
31+
```
32+
1 -> 2 -> 3 -> 4 -> 5 -> 6
33+
```
34+
35+
### Real-world Analogy
36+
Imagine we have a series of rooms (nodes), where each room has one door (node connection) that leads to another room. Our task is to rearrange the rooms in such a way that there's only one straight hallway (linked list) connecting them all, while preserving their order as they would appear in a depth-first search of the original layout.
37+
38+
**Edge Cases**:
39+
- An empty tree (`root = null`).
40+
- A tree with only one node.
41+
- A tree where every node has only a left child or only a right child.
42+
43+
---
44+
45+
### Step 2: Approach
46+
47+
#### High-Level Overview
48+
To solve this problem, we use the **Morris Traversal** technique to modify the tree in-place. The basic idea is to find the rightmost node of the left subtree (the in-order predecessor) for each node and link it to the current node's right subtree. Then, we shift the left subtree to the right and continue to the next node.
49+
50+
#### Step-by-Step Breakdown
51+
52+
1. **Start at the Root Node**: Initialize a pointer `current` to traverse the tree starting from `root`.
53+
2. **Process Each Node**:
54+
- If `current` has a left child, find its in-order predecessor in the left subtree:
55+
- Traverse to the rightmost node in `current`'s left subtree.
56+
- **Link the Right Subtree**: Link this rightmost node's right pointer to `current`'s right subtree.
57+
- **Move the Left Subtree**: Move the left subtree to the right and set `current`'s left pointer to null.
58+
3. **Continue to the Right Subtree**: Move `current` to `current->right` and repeat until all nodes are visited.
59+
60+
#### Visual Aid
61+
Here’s how the transformation works for each step in the above example:
62+
63+
```
64+
Original Tree:
65+
1
66+
/ \
67+
2 5
68+
/ \ \
69+
3 4 6
70+
71+
Step-by-Step Transformation:
72+
1. Link 4's right to 5 (right subtree of 1), move 2 to the right of 1.
73+
2. Link 3's right to 4 (right subtree of 2), move 3 to the right of 2.
74+
75+
Final Flattened Tree:
76+
1 -> 2 -> 3 -> 4 -> 5 -> 6
77+
```
78+
79+
## Problem Solution
80+
```cpp
81+
/**
82+
* Definition for a binary tree node.
83+
* struct TreeNode {
84+
* int val;
85+
* TreeNode *left;
86+
* TreeNode *right;
87+
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
88+
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
89+
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
90+
* };
91+
*/
92+
class Solution {
93+
public:
94+
void flatten(TreeNode* root) {
95+
TreeNode* current = root;
96+
97+
while(current != NULL){
98+
if(current -> left){
99+
TreeNode* pred = current -> left;
100+
101+
while(pred -> right){
102+
pred = pred -> right;
103+
}
104+
pred -> right = current -> right;
105+
current -> right = current -> left;
106+
}
107+
108+
current -> left = NULL;
109+
current = current -> right;
110+
}
111+
}
112+
};
113+
```
114+
115+
## Problem Solution Explanation
116+
Let's go through the source code for the "Flatten Binary Tree to Linked List" problem in detail, line by line, to understand how each part contributes to the solution.
117+
118+
```cpp
119+
#include <iostream>
120+
using namespace std;
121+
122+
struct TreeNode {
123+
int val;
124+
TreeNode *left;
125+
TreeNode *right;
126+
TreeNode() : val(0), left(nullptr), right(nullptr) {}
127+
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
128+
TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
129+
};
130+
```
131+
132+
- **TreeNode Structure**: This defines a binary tree node. Each `TreeNode` has:
133+
- An integer `val` representing the value of the node.
134+
- Two pointers, `left` and `right`, pointing to the left and right children of the node.
135+
- Three constructors:
136+
- `TreeNode()` initializes a node with a default value `0` and both children as `nullptr`.
137+
- `TreeNode(int x)` initializes a node with value `x`, left child as `nullptr`, and right child as `nullptr`.
138+
- `TreeNode(int x, TreeNode *left, TreeNode *right)` initializes a node with value `x`, a left child as `left`, and a right child as `right`.
139+
140+
---
141+
142+
```cpp
143+
class Solution {
144+
public:
145+
void flatten(TreeNode* root) {
146+
TreeNode* current = root;
147+
```
148+
149+
- **Solution Class**: The `Solution` class contains the `flatten` method, which is the function that will modify the binary tree to flatten it into a linked list.
150+
- **void flatten(TreeNode* root)**: This function takes a pointer to the root of a binary tree as input.
151+
- `TreeNode* current = root;`: Initializes a pointer, `current`, to traverse the tree, starting at the root node.
152+
153+
---
154+
155+
```cpp
156+
while(current != nullptr) {
157+
```
158+
159+
- **while(current != nullptr)**: This loop iterates over each node in the tree, moving along the flattened "linked list." The loop continues until `current` becomes `nullptr`, meaning all nodes have been processed.
160+
161+
---
162+
163+
```cpp
164+
if(current->left) {
165+
TreeNode* pred = current->left;
166+
```
167+
168+
- **if(current->left)**: This checks if the current node has a left child. If it does, we need to re-arrange the left and right subtrees of `current` to continue the flattening process.
169+
- **TreeNode* pred = current->left;**: `pred` is set to the left child of `current`. This pointer will be used to find the rightmost node in the left subtree of `current`, which will help in linking the left subtree correctly.
170+
171+
---
172+
173+
```cpp
174+
while(pred->right) {
175+
pred = pred->right;
176+
}
177+
```
178+
179+
- **while(pred->right)**: This inner loop traverses the right subtree of `pred` to find the rightmost node in `current`'s left subtree.
180+
- The reason we need the rightmost node is to link it to `current`'s right subtree later on, ensuring that all nodes are still accessible in the correct order.
181+
- `pred = pred->right;`: This line moves `pred` one step to the right, iteratively finding the rightmost node in the left subtree of `current`.
182+
183+
---
184+
185+
```cpp
186+
pred->right = current->right;
187+
```
188+
189+
- **pred->right = current->right;**: Once the rightmost node (`pred`) in the left subtree of `current` is found, its `right` pointer is linked to the right subtree of `current`.
190+
- This ensures that the original right subtree of `current` is preserved and attached to the end of `current`'s left subtree.
191+
192+
---
193+
194+
```cpp
195+
current->right = current->left;
196+
current->left = nullptr;
197+
```
198+
199+
- **current->right = current->left;**: The left subtree of `current` is now assigned to the `right` of `current`, effectively moving it to the right side.
200+
- This is a crucial step as we want all left children to be removed in the final linked list, and the left subtree to be placed in the right position.
201+
- **current->left = nullptr;**: This sets `current`'s left child to `nullptr`, flattening the current node's structure as per the requirement that each node should have only a right child in the flattened list.
202+
203+
---
204+
205+
```cpp
206+
}
207+
current = current->right;
208+
}
209+
}
210+
};
211+
```
212+
213+
- **current = current->right;**: Moves `current` to its right child. Since we’ve moved the entire left subtree to the right, this line ensures that `current` progresses along the "linked list" that’s being created.
214+
- **End of While Loop**: The `while` loop ends when `current` becomes `nullptr`, indicating that all nodes have been processed and the tree is fully flattened.
215+
216+
---
217+
218+
### Summary of the Code's Functioning
219+
220+
1. For each node with a left child, we find the rightmost node of that left subtree.
221+
2. We link this rightmost node's `right` pointer to the current node’s right subtree.
222+
3. We move the left subtree to the right and set the left pointer to `nullptr`.
223+
4. Finally, we advance to the next node in the newly structured list.
224+
225+
### Example Walkthrough
226+
227+
Consider this binary tree:
228+
229+
```
230+
1
231+
/ \
232+
2 5
233+
/ \ \
234+
3 4 6
235+
```
236+
237+
Step-by-step flattening process:
238+
239+
1. **Node 1**: Has a left child, `2`. Traverse the right subtree of `2` to find `4`. Set `4`'s right to `1`'s right subtree (`5`). Move `2` to the right of `1`, setting `1`'s left to `nullptr`.
240+
- Intermediate state:
241+
```
242+
1
243+
\
244+
2
245+
/ \
246+
3 4
247+
\
248+
5
249+
\
250+
6
251+
```
252+
253+
2. **Node 2**: Has a left child, `3`. Since `3` has no right child, set `3`'s right to `2`'s right subtree (`4`). Move `3` to the right of `2`, setting `2`'s left to `nullptr`.
254+
- Intermediate state:
255+
```
256+
1
257+
\
258+
2
259+
\
260+
3
261+
\
262+
4
263+
\
264+
5
265+
\
266+
6
267+
```
268+
269+
3. **Node 3, 4, 5**: Each of these nodes has no left child, so we simply move to the right each time.
270+
271+
4. **Final Flattened List**:
272+
```
273+
1 -> 2 -> 3 -> 4 -> 5 -> 6
274+
```
275+
276+
---
277+
278+
### Step 5: Time and Space Complexity
279+
280+
- **Time Complexity**: \( O(n) \), where \( n \) is the number of nodes in the tree. Each node is visited a fixed number of times.
281+
282+
- **Space Complexity**: \( O(1) \), since we’re transforming the tree in-place without using extra space for recursion or auxiliary data structures.

0 commit comments

Comments
 (0)