|
| 1 | +<h1 align='center'>Balanced - Binary - Tree</h1> |
| 2 | + |
| 3 | +## Problem Statement |
| 4 | + |
| 5 | +**Problem URL :** [Balanced Binary Tree](https://leetcode.com/problems/balanced-binary-tree/) |
| 6 | + |
| 7 | + |
| 8 | + |
| 9 | + |
| 10 | +## Problem Explanation |
| 11 | + |
| 12 | +In this problem, we are asked to determine whether a binary tree is **balanced**. A binary tree is considered balanced if, for every node in the tree, the height difference between its left and right subtrees is at most 1. This means no subtree should be significantly deeper than the other. |
| 13 | + |
| 14 | +#### Examples: |
| 15 | + |
| 16 | +1. **Example 1**: |
| 17 | + ``` |
| 18 | + 1 |
| 19 | + / \ |
| 20 | + 2 3 |
| 21 | + / |
| 22 | + 4 |
| 23 | + ``` |
| 24 | + - This tree is **balanced** because every node meets the height difference requirement. |
| 25 | + |
| 26 | +2. **Example 2**: |
| 27 | + ``` |
| 28 | + 1 |
| 29 | + / |
| 30 | + 2 |
| 31 | + / |
| 32 | + 3 |
| 33 | + ``` |
| 34 | + - This tree is **not balanced** because the left subtree of the root has a depth difference greater than 1 compared to the non-existent right subtree. |
| 35 | + |
| 36 | +3. **Example 3**: |
| 37 | + - For an empty tree (`root == NULL`), it is considered balanced. |
| 38 | + |
| 39 | +### Step 2: Approach to Solve the Problem |
| 40 | + |
| 41 | +To determine if a binary tree is balanced, we need to calculate the heights of the left and right subtrees for every node. However, this can be optimized: |
| 42 | + |
| 43 | +1. **Top-Down vs Bottom-Up Approach**: |
| 44 | + - A **top-down** approach might involve checking each node and calculating the height separately, which can be inefficient (repeated height calculations). |
| 45 | + - A **bottom-up** approach, where we calculate heights while checking the balance condition, can be more efficient, as we avoid repeated calculations. |
| 46 | + |
| 47 | +2. **Optimized Approach**: |
| 48 | + - Traverse the tree using a recursive helper function (`height`). |
| 49 | + - If any subtree is unbalanced, immediately return `-1` up the recursive chain. |
| 50 | + - If the subtree is balanced, return its height. |
| 51 | + - This way, we only need to traverse each node once, avoiding redundant calculations. |
| 52 | + |
| 53 | +## Problem Solution |
| 54 | +```cpp |
| 55 | +/** |
| 56 | + * Definition for a binary tree node. |
| 57 | + * struct TreeNode { |
| 58 | + * int val; |
| 59 | + * TreeNode *left; |
| 60 | + * TreeNode *right; |
| 61 | + * TreeNode() : val(0), left(nullptr), right(nullptr) {} |
| 62 | + * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} |
| 63 | + * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} |
| 64 | + * }; |
| 65 | + */ |
| 66 | +class Solution { |
| 67 | +private: |
| 68 | + int height(TreeNode* root){ |
| 69 | + if(root == NULL) return 0; |
| 70 | + |
| 71 | + int left = height(root -> left); |
| 72 | + if(left == -1) return -1; |
| 73 | + |
| 74 | + int right = height(root -> right); |
| 75 | + if(right == -1) return -1; |
| 76 | + |
| 77 | + |
| 78 | + if(abs(left - right) > 1) return -1; |
| 79 | + |
| 80 | + return max(left, right) + 1; |
| 81 | + } |
| 82 | +public: |
| 83 | + bool isBalanced(TreeNode* root) { |
| 84 | + return height(root) != -1; |
| 85 | + } |
| 86 | +}; |
| 87 | +``` |
| 88 | +
|
| 89 | +## Problem Solution Explanation |
| 90 | +
|
| 91 | +Here is the code with line-by-line explanations: |
| 92 | +
|
| 93 | +```cpp |
| 94 | +class Solution { |
| 95 | +private: |
| 96 | + int height(TreeNode* root) { |
| 97 | + if (root == NULL) return 0; |
| 98 | +``` |
| 99 | +- **Explanation**: If `root` is `NULL`, it means we've reached a leaf node, so we return `0` (base case). |
| 100 | + |
| 101 | +```cpp |
| 102 | + int left = height(root -> left); |
| 103 | + if (left == -1) return -1; |
| 104 | +``` |
| 105 | +- **Explanation**: |
| 106 | + - Recursively calculate the height of the left subtree. |
| 107 | + - If `left` returns `-1`, it means the left subtree is unbalanced, so we return `-1` to indicate the tree is unbalanced. |
| 108 | + |
| 109 | +```cpp |
| 110 | + int right = height(root -> right); |
| 111 | + if (right == -1) return -1; |
| 112 | +``` |
| 113 | +- **Explanation**: |
| 114 | + - Similarly, calculate the height of the right subtree. |
| 115 | + - If `right` returns `-1`, it means the right subtree is unbalanced, so we return `-1`. |
| 116 | + |
| 117 | +```cpp |
| 118 | + if (abs(left - right) > 1) return -1; |
| 119 | +``` |
| 120 | +- **Explanation**: |
| 121 | + - Check if the current node's subtrees have a height difference greater than `1`. If true, return `-1` to indicate the tree is unbalanced. |
| 122 | + |
| 123 | +```cpp |
| 124 | + return max(left, right) + 1; |
| 125 | + } |
| 126 | +``` |
| 127 | +- **Explanation**: |
| 128 | + - If the node is balanced, return the height of the subtree rooted at this node as `1 + max(left, right)`. |
| 129 | + |
| 130 | +```cpp |
| 131 | +public: |
| 132 | + bool isBalanced(TreeNode* root) { |
| 133 | + return height(root) != -1; |
| 134 | + } |
| 135 | +}; |
| 136 | +``` |
| 137 | +- **Explanation**: |
| 138 | + - `isBalanced` calls the `height` helper function and checks if it returns anything other than `-1`. |
| 139 | + - If `height` returns `-1`, it indicates the tree is unbalanced; otherwise, the tree is balanced. |
| 140 | +
|
| 141 | +### Step-by-Step Example Walkthrough |
| 142 | +
|
| 143 | +Consider the tree: |
| 144 | +
|
| 145 | +``` |
| 146 | + 1 |
| 147 | + / \ |
| 148 | + 2 3 |
| 149 | + / |
| 150 | + 4 |
| 151 | +``` |
| 152 | +
|
| 153 | +1. **Node 4**: |
| 154 | + - Both left and right subtrees are `NULL`, so their heights are `0`. |
| 155 | + - Height difference is `0`, so `height(4) = 1`. |
| 156 | +2. **Node 2**: |
| 157 | + - Left subtree (node `4`) has a height of `1`. |
| 158 | + - Right subtree is `NULL`, height `0`. |
| 159 | + - Height difference is `1`, so `height(2) = 2`. |
| 160 | +3. **Node 3**: |
| 161 | + - Both left and right subtrees are `NULL`, so height is `1`. |
| 162 | +4. **Node 1**: |
| 163 | + - Left subtree (node `2`) has a height of `2`. |
| 164 | + - Right subtree (node `3`) has a height of `1`. |
| 165 | + - Height difference is `1`, so `height(1) = 3`. |
| 166 | +
|
| 167 | +The function returns `true`, indicating the tree is balanced. |
| 168 | +
|
| 169 | +### Step 4: Time and Space Complexity |
| 170 | +
|
| 171 | +1. **Time Complexity**: **O(N)**, where `N` is the number of nodes in the tree. |
| 172 | + - Each node is visited once, and the height of each subtree is calculated in constant time. |
| 173 | +
|
| 174 | +2. **Space Complexity**: **O(H)**, where `H` is the height of the tree. |
| 175 | + - This space is used by the recursion stack. In the worst case (skewed tree), it could be `N`, while in a balanced tree, it’s `log(N)`. |
0 commit comments