|
| 1 | +<h1 align='center'>Validate - Binary - Search - Tree</h1> |
| 2 | + |
| 3 | +## Problem Statement |
| 4 | + |
| 5 | +**Problem URL :** [Validate Binary Search Tree](https://leetcode.com/problems/validate-binary-search-tree/) |
| 6 | + |
| 7 | + |
| 8 | + |
| 9 | + |
| 10 | +## Problem Explanation |
| 11 | +Given a binary tree, determine if it is a valid binary search tree (BST). In a valid BST: |
| 12 | +1. Each node's left subtree contains only nodes with values less than the node’s value. |
| 13 | +2. Each node's right subtree contains only nodes with values greater than the node’s value. |
| 14 | +3. Both the left and right subtrees must also be binary search trees. |
| 15 | + |
| 16 | +**Example**: |
| 17 | +Let's look at an example to clarify: |
| 18 | +```plaintext |
| 19 | + 2 |
| 20 | + / \ |
| 21 | + 1 3 |
| 22 | +``` |
| 23 | +This tree is a valid BST because: |
| 24 | +- The left child `1` is less than `2`. |
| 25 | +- The right child `3` is greater than `2`. |
| 26 | + |
| 27 | +Another example: |
| 28 | +```plaintext |
| 29 | + 5 |
| 30 | + / \ |
| 31 | + 1 4 |
| 32 | + / \ |
| 33 | + 3 6 |
| 34 | +``` |
| 35 | +This tree is not a valid BST because `3` is in the right subtree of `5` but is less than `5`. |
| 36 | + |
| 37 | +**Constraints**: |
| 38 | +- The number of nodes in the tree is in the range `[1, 10^4]`. |
| 39 | +- `-2^31 <= Node.val <= 2^31 - 1` |
| 40 | + |
| 41 | +**Edge Cases**: |
| 42 | +1. A single-node tree is always a valid BST. |
| 43 | +2. If all nodes have the same value, the tree cannot be a valid BST (except when there's only one node). |
| 44 | +3. An empty tree is considered a valid BST. |
| 45 | + |
| 46 | +--- |
| 47 | + |
| 48 | +### Step 2: Approach |
| 49 | + |
| 50 | +To check if a tree is a valid BST, we need to validate that each node follows the BST property by setting boundaries (minimum and maximum values) for each node. |
| 51 | + |
| 52 | +**Recursive Approach**: |
| 53 | +1. Start at the root node, initially allowing the range `(-∞, ∞)` for its value. |
| 54 | +2. For each node: |
| 55 | + - If the node’s value is not within its allowable range (`min < val < max`), return `false`. |
| 56 | + - Recur for the left subtree with an updated maximum (`max = node.val`). |
| 57 | + - Recur for the right subtree with an updated minimum (`min = node.val`). |
| 58 | +3. If every node respects the constraints in its subtree, the tree is a valid BST. |
| 59 | + |
| 60 | +## Problem Solution |
| 61 | +```cpp |
| 62 | +/** |
| 63 | + * Definition for a binary tree node. |
| 64 | + * struct TreeNode { |
| 65 | + * int val; |
| 66 | + * TreeNode *left; |
| 67 | + * TreeNode *right; |
| 68 | + * TreeNode() : val(0), left(nullptr), right(nullptr) {} |
| 69 | + * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} |
| 70 | + * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} |
| 71 | + * }; |
| 72 | + */ |
| 73 | +class Solution { |
| 74 | +public: |
| 75 | + bool isBST(TreeNode* root, long min, long max){ |
| 76 | + if(root == NULL) return true; |
| 77 | + |
| 78 | + if(root -> val > min && root -> val < max){ |
| 79 | + bool left = isBST(root -> left, min, root -> val); |
| 80 | + bool right = isBST(root -> right, root -> val, max); |
| 81 | + |
| 82 | + return left && right; |
| 83 | + }else{ |
| 84 | + return false; |
| 85 | + } |
| 86 | + } |
| 87 | + bool isValidBST(TreeNode* root) { |
| 88 | + return isBST(root, LONG_MIN, LONG_MAX); |
| 89 | + } |
| 90 | +}; |
| 91 | +``` |
| 92 | +
|
| 93 | +## Problem Solution Explanation |
| 94 | +
|
| 95 | +Let's walk through the code line by line. |
| 96 | +
|
| 97 | +```cpp |
| 98 | +/** |
| 99 | + * Definition for a binary tree node. |
| 100 | + * struct TreeNode { |
| 101 | + * int val; |
| 102 | + * TreeNode *left; |
| 103 | + * TreeNode *right; |
| 104 | + * TreeNode() : val(0), left(nullptr), right(nullptr) {} |
| 105 | + * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} |
| 106 | + * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} |
| 107 | + * }; |
| 108 | + */ |
| 109 | +``` |
| 110 | +The `TreeNode` structure is a basic representation of each node in a binary tree. Each node has: |
| 111 | +- `val`: the node’s value, |
| 112 | +- `left`: a pointer to the left child, |
| 113 | +- `right`: a pointer to the right child. |
| 114 | + |
| 115 | +```cpp |
| 116 | +class Solution { |
| 117 | +public: |
| 118 | + bool isBST(TreeNode* root, long min, long max) { |
| 119 | +``` |
| 120 | +- **Function**: `isBST` |
| 121 | +- **Purpose**: Recursively check if the tree is a valid BST within the given range `(min, max)`. |
| 122 | +
|
| 123 | +```cpp |
| 124 | + if(root == NULL) return true; |
| 125 | +``` |
| 126 | +- Base Case: If `root` is `NULL`, it means we've reached the end of a path, and no BST violation was found, so we return `true`. |
| 127 | + |
| 128 | +```cpp |
| 129 | + if(root->val > min && root->val < max) { |
| 130 | +``` |
| 131 | +- Check if `root->val` is within the allowed range `(min, max)`. |
| 132 | +- If it’s not, the tree is not a valid BST, so we return `false`. |
| 133 | +
|
| 134 | +```cpp |
| 135 | + bool left = isBST(root->left, min, root->val); |
| 136 | + bool right = isBST(root->right, root->val, max); |
| 137 | +``` |
| 138 | +- Recursive Checks: |
| 139 | + - **Left Subtree**: Call `isBST` on `root->left` with an updated `max = root->val`. |
| 140 | + - **Right Subtree**: Call `isBST` on `root->right` with an updated `min = root->val`. |
| 141 | + - Store the results in `left` and `right`. |
| 142 | + |
| 143 | +```cpp |
| 144 | + return left && right; |
| 145 | +``` |
| 146 | +- Combine results: Return `true` only if both `left` and `right` subtrees are valid BSTs. |
| 147 | + |
| 148 | +```cpp |
| 149 | + } else { |
| 150 | + return false; |
| 151 | + } |
| 152 | +``` |
| 153 | +- If `root->val` is not within the range, return `false`. |
| 154 | +
|
| 155 | +```cpp |
| 156 | + } |
| 157 | + bool isValidBST(TreeNode* root) { |
| 158 | + return isBST(root, LONG_MIN, LONG_MAX); |
| 159 | + } |
| 160 | +}; |
| 161 | +``` |
| 162 | +- **isValidBST**: Initializes the recursion with `LONG_MIN` and `LONG_MAX` boundaries for the root node. |
| 163 | + |
| 164 | +### Step 4: Output Examples |
| 165 | + |
| 166 | +**Example 1**: |
| 167 | +Input: |
| 168 | +```plaintext |
| 169 | + 2 |
| 170 | + / \ |
| 171 | + 1 3 |
| 172 | +``` |
| 173 | +Output: `true` |
| 174 | +Explanation: This tree satisfies the BST properties. |
| 175 | + |
| 176 | +**Example 2**: |
| 177 | +Input: |
| 178 | +```plaintext |
| 179 | + 5 |
| 180 | + / \ |
| 181 | + 1 4 |
| 182 | + / \ |
| 183 | + 3 6 |
| 184 | +``` |
| 185 | +Output: `false` |
| 186 | +Explanation: The node with value `3` in the right subtree of `5` is less than `5`, so it violates the BST property. |
| 187 | + |
| 188 | + |
| 189 | +### Step 5: Time and Space Complexity |
| 190 | + |
| 191 | +**Time Complexity**: \(O(n)\) |
| 192 | +- Each node is visited once, so the time complexity is linear with respect to the number of nodes. |
| 193 | + |
| 194 | +**Space Complexity**: \(O(h)\) |
| 195 | +- This is the height of the tree, which corresponds to the recursive call stack. In the worst case (for a skewed tree), this is \(O(n)\), and in the best case (balanced tree), it is \(O(\log n)\). |
| 196 | + |
| 197 | + |
| 198 | +### Additional Tips: |
| 199 | +- **Binary Tree Properties**: Understanding the properties of BSTs is crucial for this problem. |
| 200 | +- **Edge Cases**: Testing for edge cases such as null trees, single-node trees, and trees with duplicate values can help ensure the code is robust. |
| 201 | + |
0 commit comments