Skip to content

Commit 75e2dbc

Browse files
authored
Create README.md
1 parent a79cfa4 commit 75e2dbc

File tree

1 file changed

+200
-0
lines changed

1 file changed

+200
-0
lines changed
Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
<h1 align='center'>Normal - BST - to - Balanced - BST</h1>
2+
3+
## Problem Statement
4+
5+
**Problem URL :** [Normal BST to Balanced BST](https://www.geeksforgeeks.org/problems/normal-bst-to-balanced-bst/1)
6+
7+
![image](https://github.com/user-attachments/assets/4aa769d6-7a88-42bc-b94a-56d4d97239d2)
8+
![image](https://github.com/user-attachments/assets/a22011cd-dfb8-4315-a246-3321e949a0a6)
9+
10+
## Problem Explanation
11+
Given a Binary Search Tree (BST) that may not be balanced, the task is to convert it into a **balanced** BST while keeping the same values. A balanced BST has a structure where the height difference between the left and right subtrees of any node is no more than 1. This ensures that search operations remain efficient in terms of time complexity.
12+
13+
#### Approach to Solve the Problem
14+
15+
1. **Perform an In-Order Traversal**:
16+
- In-order traversal of a BST visits nodes in ascending order, resulting in a sorted sequence of values.
17+
- By storing this sequence in an array or vector, we obtain the sorted values of the BST nodes.
18+
19+
2. **Rebuild the Tree Using the Sorted Array**:
20+
- Once we have a sorted array of nodes, we can recursively build a balanced BST.
21+
- By choosing the middle element of the array (or subarray) as the root in each recursive step, we ensure a balanced structure. This divides the array into two halves around the middle element, creating left and right subtrees recursively.
22+
23+
#### Example
24+
25+
Consider a skewed BST like this:
26+
```
27+
10
28+
\
29+
20
30+
\
31+
30
32+
\
33+
40
34+
```
35+
36+
In-order traversal of this BST gives: `[10, 20, 30, 40]`.
37+
38+
If we build a balanced BST from this sorted array:
39+
```
40+
20
41+
/ \
42+
10 30
43+
\
44+
40
45+
```
46+
47+
This balanced structure has a more even height, improving search efficiency.
48+
49+
## Problem Solution
50+
```cpp
51+
class Solution{
52+
53+
public:
54+
void inOrder(Node* root, vector<Node*> &in_nodes){
55+
if(root == NULL) return;
56+
57+
inOrder(root -> left, in_nodes);
58+
in_nodes.push_back(root);
59+
inOrder(root -> right, in_nodes);
60+
}
61+
62+
Node* inOrderToBST(int start, int end, vector<Node*> &in_nodes){
63+
if(start > end) return NULL;
64+
65+
int mid = start + (end - start) / 2;
66+
Node* root = in_nodes[mid];
67+
68+
root -> left = inOrderToBST(start, mid-1, in_nodes);
69+
root -> right = inOrderToBST(mid+1, end, in_nodes);
70+
71+
return root;
72+
}
73+
74+
75+
76+
Node* buildBalancedTree(Node* root)
77+
{
78+
vector<Node*> in_nodes;
79+
inOrder(root, in_nodes);
80+
return inOrderToBST(0, in_nodes.size()-1, in_nodes);
81+
}
82+
};
83+
84+
```
85+
86+
## Problem Solution Explanation
87+
88+
```cpp
89+
class Solution{
90+
91+
public:
92+
```
93+
- Defines the `Solution` class with public member functions.
94+
95+
```cpp
96+
void inOrder(Node* root, vector<Node*> &in_nodes){
97+
if(root == NULL) return;
98+
```
99+
- `inOrder` is a helper function to perform an in-order traversal of the BST.
100+
- If `root` is `NULL`, it means there is no node to process, so it returns immediately.
101+
102+
```cpp
103+
inOrder(root -> left, in_nodes);
104+
in_nodes.push_back(root);
105+
inOrder(root -> right, in_nodes);
106+
}
107+
```
108+
- This function recursively traverses the left subtree, adds the current node (`root`) to the `in_nodes` vector, and then traverses the right subtree.
109+
- The result is a sorted vector `in_nodes` containing all nodes of the BST in ascending order.
110+
111+
```cpp
112+
Node* inOrderToBST(int start, int end, vector<Node*> &in_nodes){
113+
if(start > end) return NULL;
114+
```
115+
- `inOrderToBST` is a recursive function that builds a balanced BST from the sorted nodes stored in `in_nodes`.
116+
- If `start > end`, it means there are no nodes to form a subtree, so it returns `NULL`.
117+
118+
```cpp
119+
int mid = start + (end - start) / 2;
120+
Node* root = in_nodes[mid];
121+
```
122+
- Calculates the `mid` index of the current range, which represents the middle element of the array.
123+
- This middle element becomes the root of the current subtree, ensuring balance in the resulting BST.
124+
125+
```cpp
126+
root -> left = inOrderToBST(start, mid-1, in_nodes);
127+
root -> right = inOrderToBST(mid+1, end, in_nodes);
128+
```
129+
- Recursively sets the `left` child to a balanced subtree built from elements to the left of `mid`.
130+
- Recursively sets the `right` child to a balanced subtree built from elements to the right of `mid`.
131+
132+
```cpp
133+
return root;
134+
}
135+
```
136+
- Returns the `root` of the subtree, which will be linked to the main balanced BST.
137+
138+
```cpp
139+
Node* buildBalancedTree(Node* root)
140+
{
141+
vector<Node*> in_nodes;
142+
inOrder(root, in_nodes);
143+
return inOrderToBST(0, in_nodes.size()-1, in_nodes);
144+
}
145+
};
146+
```
147+
- `buildBalancedTree` is the main function that creates the balanced BST.
148+
- First, it performs an in-order traversal using `inOrder` to populate `in_nodes` with nodes in sorted order.
149+
- Then, it calls `inOrderToBST` to construct the balanced BST from `in_nodes` and returns the root of the balanced BST.
150+
151+
### Step 3: Example Walkthrough
152+
153+
Consider a skewed BST:
154+
```
155+
10
156+
\
157+
20
158+
\
159+
30
160+
\
161+
40
162+
```
163+
164+
1. **In-Order Traversal**:
165+
- The `inOrder` function will fill `in_nodes` with `[10, 20, 30, 40]`.
166+
167+
2. **Rebuilding as Balanced BST**:
168+
- `inOrderToBST` with `start = 0` and `end = 3`:
169+
- **Root Node**: `in_nodes[1]` (20) becomes the root.
170+
- **Left Subtree**:
171+
- `inOrderToBST(0, 0)` creates a subtree rooted at `10`.
172+
- **Right Subtree**:
173+
- `inOrderToBST(2, 3)` creates a subtree rooted at `30`, with `40` as its right child.
174+
175+
The resulting balanced BST is:
176+
```
177+
20
178+
/ \
179+
10 30
180+
\
181+
40
182+
```
183+
184+
### Step 4: Time and Space Complexity
185+
186+
1. **Time Complexity**:
187+
- **In-Order Traversal**: \( O(n) \) for traversing the tree and storing nodes in `in_nodes`.
188+
- **Balanced Tree Construction**: \( O(n) \), as each node is processed once in `inOrderToBST`.
189+
- **Total Time Complexity**: \( O(n) \).
190+
191+
2. **Space Complexity**:
192+
- **Auxiliary Space for Vector**: \( O(n) \), to store the nodes.
193+
- **Recursive Call Stack**: \( O(\log n) \) for a balanced tree, up to \( O(n) \) for a skewed tree.
194+
- **Total Space Complexity**: \( O(n) \).
195+
196+
### Step 5: Recommendations for Students
197+
198+
- **Understand In-Order Traversal**: This traversal is fundamental in working with BSTs. Practice it to solidify your understanding.
199+
- **Recursive Tree Construction**: Building trees recursively from a sorted list is a powerful concept. It helps in constructing balanced structures for efficient search operations.
200+
- **Time and Space Complexity Analysis**: Knowing how to calculate and understand complexities is essential for optimizing your code, especially with larger inputs.

0 commit comments

Comments
 (0)