-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
111 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
# [Validate Binary Search Tree](https://leetcode.com/problems/validate-binary-search-tree/description/) | ||
|
||
## Intuition | ||
|
||
To validate whether a binary tree is a binary search tree (BST), we need to ensure that each node satisfies the BST | ||
property: | ||
|
||
1. The left subtree of a node contains only nodes with keys less than the node’s key. | ||
2. The right subtree of a node contains only nodes with keys greater than the node’s key. | ||
|
||
The problem can be approached using a breadth-first search (BFS), where each node is checked against the valid range of | ||
values it can have, derived from its parent nodes. | ||
|
||
## Approach | ||
|
||
1. **Breadth-First Search (BFS):** | ||
- Use a queue to traverse the tree level by level. | ||
- Each element in the queue is a tuple (`Tuple3<TreeNode, Long, Long>`) that contains: | ||
- The current node. | ||
- The valid minimum (`min`) value the node can have. | ||
- The valid maximum (`max`) value the node can have. | ||
- For each node, check whether its value lies within the valid range: | ||
- If `node.value` is not within `[min, max]`, the tree is invalid, so return `false`. | ||
- Otherwise, update the range for the left and right children: | ||
- Left child: `max` becomes the value of the current node. | ||
- Right child: `min` becomes the value of the current node. | ||
2. **Return True for a Valid BST:** If the queue becomes empty without finding any violations of the BST property, | ||
return `true`. | ||
|
||
## Complexity | ||
|
||
- **Time Complexity: `O(n)`**, where `n` is the number of nodes in the tree. Each node is processed once. | ||
- **Space Complexity: `O(n)`**, for the queue, which may contain up to `n` nodes in the worst case (e.g., a complete | ||
binary tree). | ||
|
||
## Code | ||
|
||
- [Java](../src/main/java/io/dksifoua/leetcode/validatebinarysearchtree/Solution.java) | ||
|
||
## Summary | ||
|
||
This BFS solution ensures each node is validated against the BST property by maintaining a valid range for its values, | ||
derived from its parent nodes. The use of a queue and tuples makes the implementation clear and avoids recursion stack | ||
overhead, providing an efficient `O(n)` time complexity. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
package io.dksifoua.leetcode.utils; | ||
|
||
public record Tuple3<T, U, V>(T first, U second, V third) { | ||
}; |
30 changes: 30 additions & 0 deletions
30
src/main/java/io/dksifoua/leetcode/validatebinarysearchtree/Solution.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package io.dksifoua.leetcode.validatebinarysearchtree; | ||
|
||
import io.dksifoua.leetcode.utils.TreeNode; | ||
import io.dksifoua.leetcode.utils.Tuple3; | ||
|
||
import java.util.LinkedList; | ||
import java.util.Queue; | ||
|
||
public class Solution { | ||
|
||
public boolean isValidBST(TreeNode root) { | ||
if (root == null) return true; | ||
|
||
Queue<Tuple3<TreeNode, Long, Long>> queue = new LinkedList<>() {{ | ||
add(new Tuple3<>(root, Long.MIN_VALUE, Long.MAX_VALUE)); | ||
}}; | ||
while (!queue.isEmpty()) { | ||
Tuple3<TreeNode, Long, Long> tuple3 = queue.remove(); | ||
TreeNode node = tuple3.first(); | ||
long min = tuple3.second(), max = tuple3.third(); | ||
|
||
if (node.getValue() <= min || node.getValue() >= max) return false; | ||
|
||
if (node.getLeft() != null) queue.add(new Tuple3<>(node.getLeft(), min, (long) node.getValue())); | ||
if (node.getRight() != null) queue.add(new Tuple3<>(node.getRight(), (long) node.getValue(), max)); | ||
} | ||
|
||
return true; | ||
} | ||
} |
32 changes: 32 additions & 0 deletions
32
src/test/java/io/dksifoua/leetcode/validatebinarysearchtree/SolutionTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package io.dksifoua.leetcode.validatebinarysearchtree; | ||
|
||
import io.dksifoua.leetcode.utils.TreeNode; | ||
import org.junit.jupiter.api.Test; | ||
|
||
import static org.junit.jupiter.api.Assertions.assertFalse; | ||
import static org.junit.jupiter.api.Assertions.assertTrue; | ||
|
||
public class SolutionTest { | ||
|
||
final Solution solution = new Solution(); | ||
|
||
@Test | ||
void test1() { | ||
assertTrue(solution.isValidBST(TreeNode.build(new Integer[] { 2, 1, 3 }))); | ||
} | ||
|
||
@Test | ||
void test2() { | ||
assertFalse(solution.isValidBST(TreeNode.build(new Integer[] { 5, 1, 4, null, null, 3, 6 }))); | ||
} | ||
|
||
@Test | ||
void test3() { | ||
assertTrue(solution.isValidBST(TreeNode.build(new Integer[] { 2147483647 }))); | ||
} | ||
|
||
@Test | ||
void test4() { | ||
assertFalse(solution.isValidBST(TreeNode.build(new Integer[] { 2, 2, 2 }))); | ||
} | ||
} |