|
| 1 | +<h1 align='center'>Check - for - BST</h1> |
| 2 | + |
| 3 | +## Problem Statement |
| 4 | + |
| 5 | +**Problem URL :** [Check for BST](https://www.geeksforgeeks.org/problems/check-for-bst/1?itm_source=geeksforgeeks&itm_medium=article&itm_campaign=practice_card) |
| 6 | + |
| 7 | + |
| 8 | + |
| 9 | + |
| 10 | +## Problem Explanation |
| 11 | +The task is to determine if a given binary tree is a Binary Search Tree (BST). A binary tree is a BST if: |
| 12 | +1. All nodes in the left subtree of a node have values less than the node's value. |
| 13 | +2. All nodes in the right subtree of a node have values greater than the node's value. |
| 14 | +3. Both the left and right subtrees of each node must also be binary search trees. |
| 15 | + |
| 16 | +**Example**: |
| 17 | +Let's go through some examples to understand the problem better: |
| 18 | + |
| 19 | +1. **Valid BST**: |
| 20 | + ```plaintext |
| 21 | + 4 |
| 22 | + / \ |
| 23 | + 2 5 |
| 24 | + / \ |
| 25 | + 1 3 |
| 26 | + ``` |
| 27 | + This tree is a valid BST because: |
| 28 | + - Node `2` is less than `4` and greater than `1`, which satisfies BST rules for `4`. |
| 29 | + - Similarly, `5` is greater than `4`, and all nodes follow the BST conditions. |
| 30 | + |
| 31 | +2. **Invalid BST**: |
| 32 | + ```plaintext |
| 33 | + 5 |
| 34 | + / \ |
| 35 | + 1 4 |
| 36 | + / \ |
| 37 | + 3 6 |
| 38 | + ``` |
| 39 | + This is not a valid BST because node `3` is in the right subtree of `5` but is less than `5`. |
| 40 | + |
| 41 | +**Constraints**: |
| 42 | +- Number of nodes in the binary tree can vary, which affects traversal and checks. |
| 43 | +- All values are distinct, which simplifies checking. |
| 44 | + |
| 45 | +**Edge Cases**: |
| 46 | +1. An empty tree is considered a valid BST. |
| 47 | +2. A single-node tree is a valid BST. |
| 48 | +3. Trees with incorrect placements should return `false`. |
| 49 | + |
| 50 | +--- |
| 51 | + |
| 52 | +### Step 2: Approach |
| 53 | + |
| 54 | +To verify that a binary tree is a BST, we can perform an **in-order traversal**. In a BST, an in-order traversal produces values in strictly increasing order. Here’s the approach: |
| 55 | + |
| 56 | +1. **In-Order Traversal with Validation**: |
| 57 | + - Perform an in-order traversal of the tree, visiting the left subtree, then the current node, and finally the right subtree. |
| 58 | + - Track the last visited node (using a `prev` pointer) and compare it with the current node. If any node’s value is less than or equal to the `prev` node’s value, the tree is not a BST. |
| 59 | +2. **Base Case**: |
| 60 | + - If the node is `NULL`, return `true` since an empty tree or subtree is valid by definition. |
| 61 | + |
| 62 | +## Problem Solution |
| 63 | +```cpp |
| 64 | +class Solution { |
| 65 | + public: |
| 66 | + bool isBST(Node* root, Node* & prev){ |
| 67 | + if(root == NULL) return true; |
| 68 | + |
| 69 | + if(!isBST(root -> left, prev)) return false; |
| 70 | + |
| 71 | + if(prev != NULL && root -> data <= prev -> data) return false; |
| 72 | + |
| 73 | + prev = root; |
| 74 | + |
| 75 | + return isBST(root -> right, prev); |
| 76 | + |
| 77 | + } |
| 78 | + |
| 79 | + bool isBST(Node* root) { |
| 80 | + Node* prev = NULL; |
| 81 | + return isBST(root, prev); |
| 82 | + } |
| 83 | +}; |
| 84 | + |
| 85 | +``` |
| 86 | +
|
| 87 | +## Problem Solution Explanation |
| 88 | +Let’s examine the code line by line. |
| 89 | +
|
| 90 | +```cpp |
| 91 | +class Solution { |
| 92 | + public: |
| 93 | + bool isBST(Node* root, Node* &prev) { |
| 94 | +``` |
| 95 | +- **Function**: `isBST` |
| 96 | +- **Purpose**: Recursively checks if the tree rooted at `root` is a BST. |
| 97 | +- **Parameters**: |
| 98 | + - `Node* root`: Current node in the tree. |
| 99 | + - `Node* &prev`: Reference to the previous node visited in in-order traversal. The reference allows us to update `prev` in recursive calls. |
| 100 | + |
| 101 | +```cpp |
| 102 | + if(root == NULL) return true; |
| 103 | +``` |
| 104 | +- **Base Case**: If `root` is `NULL`, the function returns `true`, indicating this subtree (or lack of one) is valid. |
| 105 | + |
| 106 | +```cpp |
| 107 | + if(!isBST(root->left, prev)) return false; |
| 108 | +``` |
| 109 | +- **Recursive Left Subtree Check**: Recursively check the left subtree. If it’s not a BST, return `false` immediately. |
| 110 | + |
| 111 | +```cpp |
| 112 | + if(prev != NULL && root->data <= prev->data) return false; |
| 113 | +``` |
| 114 | +- **BST Validation**: If `prev` is not `NULL`, check if `root->data` is greater than `prev->data`. If it’s not, the BST property is violated, and we return `false`. |
| 115 | + |
| 116 | +```cpp |
| 117 | + prev = root; |
| 118 | +``` |
| 119 | +- **Update `prev`**: Set `prev` to the current node after confirming the left subtree and the current node satisfy the BST properties. |
| 120 | + |
| 121 | +```cpp |
| 122 | + return isBST(root->right, prev); |
| 123 | +``` |
| 124 | +- **Recursive Right Subtree Check**: Continue checking the right subtree. Return the result of this recursive check. |
| 125 | + |
| 126 | +```cpp |
| 127 | + } |
| 128 | + |
| 129 | + bool isBST(Node* root) { |
| 130 | + Node* prev = NULL; |
| 131 | + return isBST(root, prev); |
| 132 | + } |
| 133 | +}; |
| 134 | +``` |
| 135 | +- **Wrapper Function**: `isBST` initializes `prev` as `NULL` and starts the recursion. |
| 136 | +
|
| 137 | +--- |
| 138 | +
|
| 139 | +### Step 4: Output Examples |
| 140 | +
|
| 141 | +1. **Example 1**: |
| 142 | + ```plaintext |
| 143 | + 2 |
| 144 | + / \ |
| 145 | + 1 3 |
| 146 | + ``` |
| 147 | + **Input**: Root of the tree above. |
| 148 | + **Output**: `true` |
| 149 | + **Explanation**: The tree follows the BST property, with `1 < 2 < 3`. |
| 150 | + |
| 151 | +2. **Example 2**: |
| 152 | + ```plaintext |
| 153 | + 5 |
| 154 | + / \ |
| 155 | + 1 4 |
| 156 | + / \ |
| 157 | + 3 6 |
| 158 | + ``` |
| 159 | + **Input**: Root of the tree above. |
| 160 | + **Output**: `false` |
| 161 | + **Explanation**: The tree does not follow the BST property since `3` is less than `5` but is in the right subtree of `5`. |
| 162 | + |
| 163 | +3. **Edge Case (Single Node)**: |
| 164 | + ```plaintext |
| 165 | + 1 |
| 166 | + ``` |
| 167 | + **Input**: A single-node tree. |
| 168 | + **Output**: `true` |
| 169 | + **Explanation**: A single node tree is always a valid BST. |
| 170 | + |
| 171 | +--- |
| 172 | + |
| 173 | +### Step 5: Time and Space Complexity |
| 174 | + |
| 175 | +**Time Complexity**: \(O(n)\) |
| 176 | +- Each node is visited once during the in-order traversal, making the time complexity \(O(n)\), where `n` is the number of nodes in the tree. |
| 177 | + |
| 178 | +**Space Complexity**: \(O(h)\) |
| 179 | +- The space complexity is determined by the height `h` of the tree, due to the recursive call stack. In the worst case (skewed tree), this can be \(O(n)\), and in the best case (balanced tree), it is \(O(\log n)\). |
| 180 | + |
| 181 | +### Additional Tips |
| 182 | + |
| 183 | +- **Edge Cases Handling**: Consider special cases like single-node trees and trees where all nodes have the same value. |
| 184 | +- **Improvement**: To save space, an iterative approach could replace the recursion if memory usage is a concern in very deep trees. |
0 commit comments