BST Descending Leaves - codepath/compsci_guides GitHub Wiki
Unit 8 Session 1 (Click for link to problem statements)
Problem Highlights
- 💡 Difficulty: Medium
- ⏰ Time to complete: 15 mins
- 🛠️ Topics: Trees, Binary Search Trees, Tree Traversal, Sorting
1: U-nderstand
Understand what the interviewer is asking for by using test cases and questions about the problem.
- Established a set (2-3) of test cases to verify their own solution later.
- Established a set (1-2) of edge cases to verify their solution handles complexities.
- Have fully understood the problem and have no clarifying questions.
- Have you verified any Time/Space Constraints for this problem?
- Question: What if the tree is empty?
- Answer: Return an empty list as there are no leaves to collect.
HAPPY CASE
Input: TreeNode(10, TreeNode(5), TreeNode(15, None, TreeNode(20)))
Output: [20, 5]
Explanation: The leaves are the nodes with values 5 and 20, and they are listed in descending order.
EDGE CASE
Input: TreeNode(10)
Output: [10]
Explanation: The single node is both a root and a leaf.
2: M-atch
Match what this problem looks like to known categories of problems, e.g. Linked List or Dynamic Programming, and strategies or patterns in those categories.
This is a leaf collection problem that involves tree traversal and sorting. The strategy aligns with post-order traversal to ensure all leaves are accessed before sorting.
3: P-lan
Plan the solution with appropriate visualizations and pseudocode.
General Idea: Traverse the tree to collect leaf nodes, then sort the collected values in descending order.
1) Define a helper function to traverse the tree and collect leaf values.
2) Start from the root and traverse to the right subtree first to facilitate descending order collection.
3) Check each node to determine if it is a leaf (i.e., no left or right children).
4) Store leaf values.
5) After traversal, the leaves collected from right to left are already in descending order.
⚠️ Common Mistakes
- Not correctly identifying leaf nodes, especially in edge cases with single nodes or unbalanced trees.
4: I-mplement
Implement the code to solve the algorithm.
def collect_leaves_descending(root, leaves):
"
Helper function to collect leaf nodes' values from the BST rooted at `root` in descending order.
The values are collected directly into the list `leaves`.
"
if root is None:
return
# First, visit the right child (to ensure descending order)
collect_leaves_descending(root.right, leaves)
# Check if it's a leaf node
if root.left is None and root.right is None:
leaves.append(root.val)
# Then, visit the left child
collect_leaves_descending(root.left, leaves)
def descending_leaves(root):
"
Return a list of leaf values in descending order from the BST rooted at `root`.
"
leaves = []
collect_leaves_descending(root, leaves)
return leaves
5: R-eview
Review the code by running specific example(s) and recording values (watchlist) of your code's variables along the way.
- Execute with a variety of test cases to ensure the leaf values are accurately collected and appropriately sorted in descending order without requiring additional sorting steps.
6: E-valuate
Evaluate the performance of your algorithm and state any strong/weak or future potential work.
- Time Complexity:
O(n)
where n is the number of nodes in the tree. Each node is visited once. - Space Complexity:
O(h)
where h is the height of the tree due to recursion, which can be up toO(n)
in unbalanced trees but is typicallyO(log n)
in balanced trees.