|
| 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 | + |
| 8 | + |
| 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