Skip to content

Commit b175c69

Browse files
committed
Validate Binary Search Tree
1 parent 9ba2597 commit b175c69

File tree

5 files changed

+111
-0
lines changed

5 files changed

+111
-0
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
| 0074 | Medium | Search a 2D Matrix | Array, Binary Search, Matrix | [solution](./docs/0074-Search-A-2D-Matrix.md) |
2424
| 0076 | Hard | Minimum Window Substring | Hash Table, String, Sliding Window | [solution](./docs/0076-Mininum-Window-Substring.md) |
2525
| 0084 | Hard | Largest Rectangle in Histogram | Array, Stack, Monotonic Stack | [solution](./docs/0084-Largest-Rectangle-In-Histogram.md) |
26+
| 0098 | Medium | Validate Binary Search Tree | Tree, Depth-First Search, Binary Search Tree, Binary Tree | [solution](./docs/0098-Validate-Binary-Search-Tree.md) |
2627
| 0100 | Easy | Same Tree | Tree, Depth-First Search, Breadth-First Search, Binary Tree | [solution](./docs/0100-Same-Tree.md) |
2728
| 0102 | Medium | Binary Tree Level Order Traversal | Tree, Breadth-First Search, Binary Tree | [solution](./docs/0102-Binary-Tree-Level-Order-Traversal.md) |
2829
| 0104 | Easy | Maximum Depth of Binary Tree | Tree, Depth-First Search, Breadth-First Search, Binary Tree | [solution](./docs/0104-Maximum-Depth-of-Binary-Tree.md) |
+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# [Validate Binary Search Tree](https://leetcode.com/problems/validate-binary-search-tree/description/)
2+
3+
## Intuition
4+
5+
To validate whether a binary tree is a binary search tree (BST), we need to ensure that each node satisfies the BST
6+
property:
7+
8+
1. The left subtree of a node contains only nodes with keys less than the node’s key.
9+
2. The right subtree of a node contains only nodes with keys greater than the node’s key.
10+
11+
The problem can be approached using a breadth-first search (BFS), where each node is checked against the valid range of
12+
values it can have, derived from its parent nodes.
13+
14+
## Approach
15+
16+
1. **Breadth-First Search (BFS):**
17+
- Use a queue to traverse the tree level by level.
18+
- Each element in the queue is a tuple (`Tuple3<TreeNode, Long, Long>`) that contains:
19+
- The current node.
20+
- The valid minimum (`min`) value the node can have.
21+
- The valid maximum (`max`) value the node can have.
22+
- For each node, check whether its value lies within the valid range:
23+
- If `node.value` is not within `[min, max]`, the tree is invalid, so return `false`.
24+
- Otherwise, update the range for the left and right children:
25+
- Left child: `max` becomes the value of the current node.
26+
- Right child: `min` becomes the value of the current node.
27+
2. **Return True for a Valid BST:** If the queue becomes empty without finding any violations of the BST property,
28+
return `true`.
29+
30+
## Complexity
31+
32+
- **Time Complexity: `O(n)`**, where `n` is the number of nodes in the tree. Each node is processed once.
33+
- **Space Complexity: `O(n)`**, for the queue, which may contain up to `n` nodes in the worst case (e.g., a complete
34+
binary tree).
35+
36+
## Code
37+
38+
- [Java](../src/main/java/io/dksifoua/leetcode/validatebinarysearchtree/Solution.java)
39+
40+
## Summary
41+
42+
This BFS solution ensures each node is validated against the BST property by maintaining a valid range for its values,
43+
derived from its parent nodes. The use of a queue and tuples makes the implementation clear and avoids recursion stack
44+
overhead, providing an efficient `O(n)` time complexity.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package io.dksifoua.leetcode.utils;
2+
3+
public record Tuple3<T, U, V>(T first, U second, V third) {
4+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package io.dksifoua.leetcode.validatebinarysearchtree;
2+
3+
import io.dksifoua.leetcode.utils.TreeNode;
4+
import io.dksifoua.leetcode.utils.Tuple3;
5+
6+
import java.util.LinkedList;
7+
import java.util.Queue;
8+
9+
public class Solution {
10+
11+
public boolean isValidBST(TreeNode root) {
12+
if (root == null) return true;
13+
14+
Queue<Tuple3<TreeNode, Long, Long>> queue = new LinkedList<>() {{
15+
add(new Tuple3<>(root, Long.MIN_VALUE, Long.MAX_VALUE));
16+
}};
17+
while (!queue.isEmpty()) {
18+
Tuple3<TreeNode, Long, Long> tuple3 = queue.remove();
19+
TreeNode node = tuple3.first();
20+
long min = tuple3.second(), max = tuple3.third();
21+
22+
if (node.getValue() <= min || node.getValue() >= max) return false;
23+
24+
if (node.getLeft() != null) queue.add(new Tuple3<>(node.getLeft(), min, (long) node.getValue()));
25+
if (node.getRight() != null) queue.add(new Tuple3<>(node.getRight(), (long) node.getValue(), max));
26+
}
27+
28+
return true;
29+
}
30+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package io.dksifoua.leetcode.validatebinarysearchtree;
2+
3+
import io.dksifoua.leetcode.utils.TreeNode;
4+
import org.junit.jupiter.api.Test;
5+
6+
import static org.junit.jupiter.api.Assertions.assertFalse;
7+
import static org.junit.jupiter.api.Assertions.assertTrue;
8+
9+
public class SolutionTest {
10+
11+
final Solution solution = new Solution();
12+
13+
@Test
14+
void test1() {
15+
assertTrue(solution.isValidBST(TreeNode.build(new Integer[] { 2, 1, 3 })));
16+
}
17+
18+
@Test
19+
void test2() {
20+
assertFalse(solution.isValidBST(TreeNode.build(new Integer[] { 5, 1, 4, null, null, 3, 6 })));
21+
}
22+
23+
@Test
24+
void test3() {
25+
assertTrue(solution.isValidBST(TreeNode.build(new Integer[] { 2147483647 })));
26+
}
27+
28+
@Test
29+
void test4() {
30+
assertFalse(solution.isValidBST(TreeNode.build(new Integer[] { 2, 2, 2 })));
31+
}
32+
}

0 commit comments

Comments
 (0)