Skip to content

Commit 9616dba

Browse files
authored
Create README.md
1 parent 751789b commit 9616dba

File tree

1 file changed

+210
-0
lines changed

1 file changed

+210
-0
lines changed
Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
<h1 align='center'>Balance - a Binary - Search - Tree</h1>
2+
3+
## Problem Statement
4+
5+
**Problem URL :** [Balance a Binary Search Tree](https://leetcode.com/problems/balance-a-binary-search-tree/)
6+
7+
![image](https://github.com/user-attachments/assets/a0f759f7-f26e-4243-a9b1-6d5bdd78af84)
8+
![image](https://github.com/user-attachments/assets/b85a4bea-d997-4c9d-88d0-f0e2f41ad669)
9+
10+
## Problem Explanation
11+
Given a **Binary Search Tree (BST)**, the task is to convert it into a **balanced BST**. A balanced BST ensures that the height difference between the left and right subtrees of any node is no more than 1. This balancing helps keep the search operations efficient.
12+
13+
#### Approach to Solve the Problem
14+
15+
1. **In-Order Traversal**:
16+
- Performing an in-order traversal of a BST visits nodes in ascending order. We store these nodes in an array or vector.
17+
- This array will contain the sorted values of the BST nodes.
18+
19+
2. **Rebuild the Balanced BST**:
20+
- Using the sorted array from the in-order traversal, we can build a balanced BST by picking the middle element as the root of each subtree. This middle element division helps keep the BST balanced.
21+
- By recursively choosing the middle element of each subarray, we ensure each subtree is balanced.
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+
Performing an in-order traversal on this BST gives the array `[10, 20, 30, 40]`.
37+
38+
Rebuilding this as a balanced BST gives:
39+
```
40+
20
41+
/ \
42+
10 30
43+
\
44+
40
45+
```
46+
47+
This balanced BST has a reduced height, making it more efficient for search operations.
48+
49+
## Problem Solution
50+
```cpp
51+
/**
52+
* Definition for a binary tree node.
53+
* struct TreeNode {
54+
* int val;
55+
* TreeNode *left;
56+
* TreeNode *right;
57+
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
58+
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
59+
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
60+
* };
61+
*/
62+
class Solution {
63+
public:
64+
void inOrder(TreeNode* root, vector<TreeNode*> &inOrderValues){
65+
if(root == NULL) return;
66+
67+
inOrder(root -> left, inOrderValues);
68+
inOrderValues.push_back(root);
69+
inOrder(root -> right, inOrderValues);
70+
}
71+
72+
TreeNode* inorderToBST(int start, int end, vector<TreeNode*> &inOrderValues){
73+
if(start > end) return NULL;
74+
75+
int mid = start + (end - start) / 2;
76+
77+
TreeNode* root = inOrderValues[mid];
78+
79+
root -> left = inorderToBST(start, mid-1, inOrderValues);
80+
root -> right = inorderToBST(mid + 1, end, inOrderValues);
81+
82+
return root;
83+
}
84+
TreeNode* balanceBST(TreeNode* root) {
85+
vector<TreeNode*> inOrderValues;
86+
inOrder(root, inOrderValues);
87+
88+
return inorderToBST(0, inOrderValues.size()-1, inOrderValues);
89+
}
90+
};
91+
```
92+
93+
## Problem Solution Explanation
94+
95+
```cpp
96+
class Solution {
97+
public:
98+
```
99+
- Defines the `Solution` class with public member functions.
100+
101+
```cpp
102+
void inOrder(TreeNode* root, vector<TreeNode*> &inOrderValues){
103+
if(root == NULL) return;
104+
```
105+
- `inOrder` is a helper function to perform an in-order traversal of the BST.
106+
- If `root` is `NULL`, it means there are no nodes to process, so it immediately returns.
107+
108+
```cpp
109+
inOrder(root -> left, inOrderValues);
110+
inOrderValues.push_back(root);
111+
inOrder(root -> right, inOrderValues);
112+
}
113+
```
114+
- This function recursively traverses the left subtree, then adds the current node (`root`) to the vector `inOrderValues`, and finally traverses the right subtree.
115+
- The result is a sorted vector `inOrderValues` containing all nodes in ascending order.
116+
117+
```cpp
118+
TreeNode* inorderToBST(int start, int end, vector<TreeNode*> &inOrderValues){
119+
if(start > end) return NULL;
120+
```
121+
- `inorderToBST` is a recursive function that builds a balanced BST from the sorted nodes in `inOrderValues`.
122+
- If `start` is greater than `end`, it means there are no nodes left to form a subtree, so it returns `NULL`.
123+
124+
```cpp
125+
int mid = start + (end - start) / 2;
126+
```
127+
- Calculates the middle index of the current range, which is the middle element of the sorted array.
128+
- This middle element becomes the root of the current subtree, ensuring balance.
129+
130+
```cpp
131+
TreeNode* root = inOrderValues[mid];
132+
```
133+
- Sets the node at the `mid` index as the root for the current subtree.
134+
135+
```cpp
136+
root -> left = inorderToBST(start, mid-1, inOrderValues);
137+
root -> right = inorderToBST(mid + 1, end, inOrderValues);
138+
```
139+
- Recursively sets the `left` child to a balanced subtree from elements left of `mid`.
140+
- Recursively sets the `right` child to a balanced subtree from elements right of `mid`.
141+
142+
```cpp
143+
return root;
144+
}
145+
```
146+
- Returns the `root` of the subtree, which will be attached to the main balanced BST.
147+
148+
```cpp
149+
TreeNode* balanceBST(TreeNode* root) {
150+
vector<TreeNode*> inOrderValues;
151+
inOrder(root, inOrderValues);
152+
```
153+
- `balanceBST` is the main function to create the balanced BST.
154+
- First, it calls `inOrder` to populate `inOrderValues` with nodes in sorted order.
155+
156+
```cpp
157+
return inorderToBST(0, inOrderValues.size()-1, inOrderValues);
158+
}
159+
};
160+
```
161+
- It then calls `inorderToBST` to construct the balanced BST from `inOrderValues` and returns the root of the new balanced BST.
162+
163+
### Step 3: Example Walkthrough
164+
165+
Consider a skewed BST like:
166+
```
167+
10
168+
\
169+
20
170+
\
171+
30
172+
\
173+
40
174+
```
175+
176+
1. **In-Order Traversal**:
177+
- The `inOrder` function will populate `inOrderValues` with `[10, 20, 30, 40]`.
178+
179+
2. **Rebuilding the Balanced BST**:
180+
- `inorderToBST(0, 3)` is called with `start = 0` and `end = 3`.
181+
- Middle index `mid = 1`, so `inOrderValues[1]` (20) becomes the root.
182+
- **Left Subtree**: `inorderToBST(0, 0)` creates a subtree with `10` as the root.
183+
- **Right Subtree**: `inorderToBST(2, 3)` creates a subtree rooted at `30`, with `40` as its right child.
184+
185+
The resulting balanced BST is:
186+
```
187+
20
188+
/ \
189+
10 30
190+
\
191+
40
192+
```
193+
194+
### Step 4: Time and Space Complexity
195+
196+
1. **Time Complexity**:
197+
- **In-Order Traversal**: \( O(n) \) to traverse and store nodes in `inOrderValues`.
198+
- **Balanced Tree Construction**: \( O(n) \), as each node is processed once in `inorderToBST`.
199+
- **Total Time Complexity**: \( O(n) \).
200+
201+
2. **Space Complexity**:
202+
- **Auxiliary Space for Vector**: \( O(n) \), for `inOrderValues`.
203+
- **Recursive Call Stack**: \( O(\log n) \) for a balanced tree and up to \( O(n) \) for a skewed tree.
204+
- **Total Space Complexity**: \( O(n) \).
205+
206+
### Step 5: Recommendations for Students
207+
208+
- **Practice In-Order Traversal**: In-order traversal is essential for working with BSTs. Get comfortable with it, as it appears often in BST problems.
209+
- **Recursive Tree Building**: Understanding recursive tree construction from sorted lists is a valuable skill that can help in similar tree problems.
210+
- **Analyze Complexity**: Be sure to understand the time and space complexity of each function and how the recursive stack works, as this can help in optimizing solutions for larger inputs.

0 commit comments

Comments
 (0)