File tree Expand file tree Collapse file tree 6 files changed +153
-3
lines changed
datastructures/trees/binary/search_tree
puzzles/search/binary_search Expand file tree Collapse file tree 6 files changed +153
-3
lines changed Original file line number Diff line number Diff line change 545545 * [ Test Cyclically Shifted Array] ( https://github.com/BrianLusina/PythonSnips/blob/master/puzzles/search/binary_search/cyclically_shifted_array/test_cyclically_shifted_array.py )
546546 * Find Closest Number
547547 * [ Test Find Closest Number] ( https://github.com/BrianLusina/PythonSnips/blob/master/puzzles/search/binary_search/find_closest_number/test_find_closest_number.py )
548+ * Find Closest Value
549+ * [ Test Find Closest Value] ( https://github.com/BrianLusina/PythonSnips/blob/master/puzzles/search/binary_search/find_closest_value/test_find_closest_value.py )
548550 * Find First In Duplicate List
549551 * [ 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 )
550552 * Find Fixed Number
Original file line number Diff line number Diff line change @@ -219,6 +219,46 @@ def find_second_largest(self) -> BinaryTreeNode:
219219
220220 return current
221221
222+ def find_closest_value_in_bst (self , target : T ) -> Optional [BinaryTreeNode ]:
223+ """
224+ Finds the closest value in the binary search tree to the given target value.
225+
226+ Args:
227+ target T: Value to search for
228+ Returns:
229+ Node with the closest value to the target
230+ """
231+ # edge case for empty nodes, if none is provided, we can't find a value that is close to the target
232+ if not self .root :
233+ return None
234+
235+ # if the node's data is the target, exit early by returning it
236+ if self .root .data == target :
237+ return self .root
238+
239+ # this keeps track of the minimum on both the left and the right
240+ closest_node = self .root
241+ min_diff = abs (target - self .root .data )
242+ current = self .root
243+
244+ # while the queue is not empty, we pop off nodes from the queue and check for their values
245+ while current :
246+ current_diff = abs (target - self .root .data )
247+
248+ if current_diff < min_diff :
249+ min_diff = current_diff
250+ closest_node = current
251+
252+ if current .data == target :
253+ return current
254+
255+ if target < current .data :
256+ current = current .left
257+ else :
258+ current = current .right
259+
260+ return closest_node
261+
222262 def range_sum (self , low : int , high : int ):
223263 """
224264 returns the sum of datas of all nodes with a data in the range [low, high].
Original file line number Diff line number Diff line change 11# Find the Closest Number
22
3- 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
4- target number. We will be making use of a binary search to solve this problem, so make sure that you have gone through
5- the previous lesson.
3+ 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
4+ target number. We will be making use of a binary search to solve this problem.
65
76The array may contain duplicate values and negative numbers.
87
Original file line number Diff line number Diff line change 1+ # Find Closest Value in BST
2+
3+ Write a function that takes in a Binary Search Tree (BST) and a target integer
4+ value and returns the closest value to that target value contained in the BST.
5+
6+ You can assume that there will only be one closest value.
7+
8+ Each <span >BST</span > node has an integer <span >value</span >, a
9+ <span >left</span > child node, and a <span >right</span > child node. A node is
10+ said to be a valid <span >BST</span > node if and only if it satisfies the BST
11+ property: its <span >value</span > is strictly greater than the values of every
12+ node to its left; its <span >value</span > is less than or equal to the values
13+ of every node to its right; and its children nodes are either valid
14+ <span >BST</span > nodes themselves or <span >None</span > / <span >null</span >.
15+
16+ Sample Input:
17+
18+ ``` text
19+ tree = 10
20+ / \
21+ 5 15
22+ / \ / \
23+ 2 5 13 22
24+ / \
25+ 1 14
26+ target = 12
27+ ```
28+
29+ Sample output: 13
30+
31+ ## Hints
32+
33+ - Try traversing the BST node by node, all the while keeping track of the node with the value closest to the target value.
34+ Calculating the absolute value of the difference between a node's value and the target value should allow you to
35+ check if that node is closer than the current closest one.
36+ - Make use of the BST property to determine what side of any given node has values close to the target value and is
37+ therefore worth exploring.
38+ - What are the advantages and disadvantages of solving this problem iteratively as opposed to recursively?
39+
40+ ## Optimal Space & Time Complexity
41+
42+ Average: O(log(n)) time | O(1) space where n is the number of nodes in the tree
43+ BST Worst: O(n) time | O(1) space where n is the number of nodes in the tree
Original file line number Diff line number Diff line change 1+ from typing import Optional
2+ from datastructures .trees .binary .search_tree import BinaryTreeNode
3+
4+
5+ def find_closest_value_in_bst (node : BinaryTreeNode , target : int ) -> Optional [int ]:
6+ # edge case for empty nodes, if none is provided, we can't find a value that is close to the target
7+ if not node :
8+ return None
9+
10+ # if the node's data is the target, exit early by returning it
11+ if node .data == target :
12+ return node .data
13+
14+ # this keeps track of the minimum on both the left and the right
15+ closest_value = node .data
16+ min_diff = abs (target - node .data )
17+ current = node
18+
19+ # while the queue is not empty, we pop off nodes from the queue and check for their values
20+ while current :
21+ current_diff = abs (target - current .data )
22+
23+ if current_diff < min_diff :
24+ min_diff = current_diff
25+ closest_value = current .data
26+
27+ if current .data == target :
28+ return current .data
29+
30+ if target < current .data :
31+ current = current .left
32+ else :
33+ current = current .right
34+
35+ return closest_value
Original file line number Diff line number Diff line change 1+ import unittest
2+ from datastructures .trees .binary .search_tree import BinaryTreeNode
3+ from . import find_closest_value_in_bst
4+
5+
6+ class FindClosestValueTestCases (unittest .TestCase ):
7+ def test_something (self ):
8+ root = BinaryTreeNode (
9+ data = 10 ,
10+ left = BinaryTreeNode (data = 5 ,
11+ left = BinaryTreeNode (
12+ data = 2 ,
13+ left = BinaryTreeNode (data = 1 ),
14+ right = BinaryTreeNode (data = 5 ))
15+ ),
16+ right = BinaryTreeNode (data = 15 ,
17+ left = BinaryTreeNode (
18+ data = 13 ,
19+ right = BinaryTreeNode (
20+ data = 14 ,
21+ right = BinaryTreeNode (data = 22 )
22+ )
23+ ))
24+ )
25+ expected = 13
26+ actual = find_closest_value_in_bst (root , target = 12 )
27+ self .assertEqual (expected , actual )
28+
29+
30+ if __name__ == '__main__' :
31+ unittest .main ()
You can’t perform that action at this time.
0 commit comments