Skip to content

Commit 8c05de3

Browse files
committed
feat(trees): find kth largest in binary search tree
1 parent f2866ba commit 8c05de3

File tree

1 file changed

+52
-1
lines changed

1 file changed

+52
-1
lines changed

datastructures/trees/binary/search_tree/__init__.py

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,57 @@ def find_second_largest(self) -> BinaryTreeNode:
249249

250250
return current
251251

252+
def find_kth_largest(self, k: int) -> Optional[BinaryTreeNode]:
253+
"""
254+
Finds the kth largest value in a binary search tree. This uses a reverse in order traversal moving from right
255+
to root to left until the kth largest node can be found. We don't have to traverse the whole tree since binary
256+
search trees are already ordered following the property of the right subtree has nodes which have the left
257+
sub-tree always less than their parent and the right subtree has nodes with values that are either equal to or
258+
greater than the parent. With this property in mind, we perform a reverse in order traversal to be able to move
259+
from right to root to left to find the kth largest node in the tree.
260+
261+
Complexity:
262+
Time: O(h + k): where h is the height of the tree and k is the input
263+
Space: O(h): where h is the height of the tree.
264+
265+
Args:
266+
k (int): The kth largest value to find
267+
Returns:
268+
Optional[BinaryTreeNode]: The kth largest node
269+
"""
270+
271+
# This is a helper class that helps to track the algorithm's progress of traversing the tree
272+
class TreeInfo:
273+
def __init__(self):
274+
self.number_of_nodes_visited: int = 0
275+
self.latest_visited_node: Optional[BinaryTreeNode] = None
276+
277+
def reverse_in_order_traverse(node: BinaryTreeNode, tree_information: TreeInfo):
278+
"""
279+
Helper function to traverse the tree in reverse in order
280+
Args:
281+
node (BinaryTreeNode): The node to traverse
282+
tree_information (TreeInfo): The tree information
283+
"""
284+
# base case: if node is None or we've already found the kth largest
285+
if not node or tree_information.number_of_nodes_visited >= k:
286+
return
287+
288+
# traverse right subtree first for larger values
289+
reverse_in_order_traverse(node.right, tree_information)
290+
291+
# Visit the current node if we haven't found k nodes yet
292+
if tree_information.number_of_nodes_visited < k:
293+
tree_information.number_of_nodes_visited += 1
294+
tree_information.latest_visited_node = node
295+
296+
# traverse the left subtree for smaller values if needed
297+
reverse_in_order_traverse(node.left, tree_information)
298+
299+
tree_info = TreeInfo()
300+
reverse_in_order_traverse(self.root, tree_info)
301+
return tree_info.latest_visited_node
302+
252303
def find_closest_value_in_bst(self, target: T) -> Optional[BinaryTreeNode]:
253304
"""
254305
Finds the closest value in the binary search tree to the given target value.
@@ -410,7 +461,7 @@ def in_order_recurse(self, node: BinaryTreeNode) -> List[T]:
410461
self.in_order_recurse(self.root.right)
411462
return result
412463

413-
def in_order_iterate(self) -> list:
464+
def in_order_iterate(self) -> List[T]:
414465
"""
415466
Iterative approach using a stack
416467
"""

0 commit comments

Comments
 (0)