diff --git a/DIRECTORY.md b/DIRECTORY.md
index 032c1824..bd7b32f2 100644
--- a/DIRECTORY.md
+++ b/DIRECTORY.md
@@ -545,6 +545,8 @@
* [Test Cyclically Shifted Array](https://github.com/BrianLusina/PythonSnips/blob/master/puzzles/search/binary_search/cyclically_shifted_array/test_cyclically_shifted_array.py)
* Find Closest Number
* [Test Find Closest Number](https://github.com/BrianLusina/PythonSnips/blob/master/puzzles/search/binary_search/find_closest_number/test_find_closest_number.py)
+ * Find Closest Value
+ * [Test Find Closest Value](https://github.com/BrianLusina/PythonSnips/blob/master/puzzles/search/binary_search/find_closest_value/test_find_closest_value.py)
* Find First In Duplicate List
* [Test Find First In Duplicates](https://github.com/BrianLusina/PythonSnips/blob/master/puzzles/search/binary_search/find_first_in_duplicate_list/test_find_first_in_duplicates.py)
* Find Fixed Number
diff --git a/datastructures/trees/binary/search_tree/__init__.py b/datastructures/trees/binary/search_tree/__init__.py
index 9c72583b..ac8a5cf1 100755
--- a/datastructures/trees/binary/search_tree/__init__.py
+++ b/datastructures/trees/binary/search_tree/__init__.py
@@ -219,6 +219,46 @@ def find_second_largest(self) -> BinaryTreeNode:
return current
+ def find_closest_value_in_bst(self, target: T) -> Optional[BinaryTreeNode]:
+ """
+ Finds the closest value in the binary search tree to the given target value.
+
+ Args:
+ target T: Value to search for
+ Returns:
+ Node with the closest value to the target
+ """
+ # edge case for empty nodes, if none is provided, we can't find a value that is close to the target
+ if not self.root:
+ return None
+
+ # if the node's data is the target, exit early by returning it
+ if self.root.data == target:
+ return self.root
+
+ # this keeps track of the minimum on both the left and the right
+ closest_node = self.root
+ min_diff = abs(target - self.root.data)
+ current = self.root
+
+ # while the queue is not empty, we pop off nodes from the queue and check for their values
+ while current:
+ current_diff = abs(target - self.root.data)
+
+ if current_diff < min_diff:
+ min_diff = current_diff
+ closest_node = current
+
+ if current.data == target:
+ return current
+
+ if target < current.data:
+ current = current.left
+ else:
+ current = current.right
+
+ return closest_node
+
def range_sum(self, low: int, high: int):
"""
returns the sum of datas of all nodes with a data in the range [low, high].
diff --git a/puzzles/search/binary_search/find_closest_number/README.md b/puzzles/search/binary_search/find_closest_number/README.md
index 1d19e0db..8dba2800 100644
--- a/puzzles/search/binary_search/find_closest_number/README.md
+++ b/puzzles/search/binary_search/find_closest_number/README.md
@@ -1,8 +1,7 @@
# Find the Closest Number
-we will be given a sorted array and a target number. Our goal is to find a number in the array that is closest to the
-target number. We will be making use of a binary search to solve this problem, so make sure that you have gone through
-the previous lesson.
+We will be given a sorted array and a target number. Our goal is to find a number in the array that is closest to the
+target number. We will be making use of a binary search to solve this problem.
The array may contain duplicate values and negative numbers.
diff --git a/puzzles/search/binary_search/find_closest_value/README.md b/puzzles/search/binary_search/find_closest_value/README.md
new file mode 100644
index 00000000..336e02b1
--- /dev/null
+++ b/puzzles/search/binary_search/find_closest_value/README.md
@@ -0,0 +1,43 @@
+# Find Closest Value in BST
+
+Write a function that takes in a Binary Search Tree (BST) and a target integer
+value and returns the closest value to that target value contained in the BST.
+
+You can assume that there will only be one closest value.
+
+Each BST node has an integer value, a
+left child node, and a right child node. A node is
+said to be a valid BST node if and only if it satisfies the BST
+property: its value is strictly greater than the values of every
+node to its left; its value is less than or equal to the values
+of every node to its right; and its children nodes are either valid
+BST nodes themselves or None / null.
+
+Sample Input:
+
+```text
+tree = 10
+ / \
+ 5 15
+ / \ / \
+ 2 5 13 22
+ / \
+1 14
+target = 12
+```
+
+Sample output: 13
+
+## Hints
+
+- Try traversing the BST node by node, all the while keeping track of the node with the value closest to the target value.
+ Calculating the absolute value of the difference between a node's value and the target value should allow you to
+ check if that node is closer than the current closest one.
+- Make use of the BST property to determine what side of any given node has values close to the target value and is
+ therefore worth exploring.
+- What are the advantages and disadvantages of solving this problem iteratively as opposed to recursively?
+
+## Optimal Space & Time Complexity
+
+Average: O(log(n)) time | O(1) space where n is the number of nodes in the tree
+BST Worst: O(n) time | O(1) space where n is the number of nodes in the tree
diff --git a/puzzles/search/binary_search/find_closest_value/__init__.py b/puzzles/search/binary_search/find_closest_value/__init__.py
new file mode 100644
index 00000000..80e5668c
--- /dev/null
+++ b/puzzles/search/binary_search/find_closest_value/__init__.py
@@ -0,0 +1,35 @@
+from typing import Optional
+from datastructures.trees.binary.search_tree import BinaryTreeNode
+
+
+def find_closest_value_in_bst(node: BinaryTreeNode, target: int) -> Optional[int]:
+ # edge case for empty nodes, if none is provided, we can't find a value that is close to the target
+ if not node:
+ return None
+
+ # if the node's data is the target, exit early by returning it
+ if node.data == target:
+ return node.data
+
+ # this keeps track of the minimum on both the left and the right
+ closest_value = node.data
+ min_diff = abs(target - node.data)
+ current = node
+
+ # while the queue is not empty, we pop off nodes from the queue and check for their values
+ while current:
+ current_diff = abs(target - current.data)
+
+ if current_diff < min_diff:
+ min_diff = current_diff
+ closest_value = current.data
+
+ if current.data == target:
+ return current.data
+
+ if target < current.data:
+ current = current.left
+ else:
+ current = current.right
+
+ return closest_value
diff --git a/puzzles/search/binary_search/find_closest_value/test_find_closest_value.py b/puzzles/search/binary_search/find_closest_value/test_find_closest_value.py
new file mode 100644
index 00000000..bc01c3cf
--- /dev/null
+++ b/puzzles/search/binary_search/find_closest_value/test_find_closest_value.py
@@ -0,0 +1,31 @@
+import unittest
+from datastructures.trees.binary.search_tree import BinaryTreeNode
+from . import find_closest_value_in_bst
+
+
+class FindClosestValueTestCases(unittest.TestCase):
+ def test_something(self):
+ root = BinaryTreeNode(
+ data=10,
+ left=BinaryTreeNode(data=5,
+ left=BinaryTreeNode(
+ data=2,
+ left=BinaryTreeNode(data=1),
+ right=BinaryTreeNode(data=5))
+ ),
+ right=BinaryTreeNode(data=15,
+ left=BinaryTreeNode(
+ data=13,
+ right=BinaryTreeNode(
+ data=14,
+ right=BinaryTreeNode(data=22)
+ )
+ ))
+ )
+ expected = 13
+ actual = find_closest_value_in_bst(root, target=12)
+ self.assertEqual(expected, actual)
+
+
+if __name__ == '__main__':
+ unittest.main()