Find shortest path in a Fibonacci-ordered tree
Company: Databricks
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: hard
Interview Round: Technical Screen
Quick Answer: This question evaluates understanding of recursive binary tree structures, preorder indexing, Fibonacci-like size relations, and arithmetic-based navigation for computing paths in an implicitly defined tree.
Constraints
- 0 <= order
- size(0) = 1 and size(1) = 1
- For k >= 2, size(k) = 1 + size(k-1) + size(k-2)
- 0 <= start, end < size(order)
- Aim for O(order) time and O(order) extra space
Examples
Input: (2, 1, 2)
Expected Output: [1, 0, 2]
Explanation: In T(2), node 1 is the left child and node 2 is the right child of root 0.
Input: (0, 0, 0)
Expected Output: [0]
Explanation: T(0) has exactly one node, so the path starts and ends at 0.
Input: (3, 3, 2)
Expected Output: [3, 1, 2]
Explanation: In T(3), nodes 3 and 2 are both under node 1, so the shortest path goes through 1.
Input: (4, 4, 5)
Expected Output: [4, 2, 1, 5]
Explanation: Both nodes are in the left subtree of T(4); their lowest common ancestor is node 1.
Input: (5, 9, 14)
Expected Output: [9, 7, 1, 0, 10, 14]
Explanation: The nodes lie in different major branches of T(5), so the path passes through the overall root 0.
Input: (4, 0, 8)
Expected Output: [0, 6, 8]
Explanation: Node 8 is in the right subtree of the root in T(4), specifically under node 6.
Input: (4, 7, 7)
Expected Output: [7]
Explanation: When start and end are the same node, the shortest path contains only that label.
Solution
def solution(order, start, end):
sizes = [1] * max(2, order + 1)
for k in range(2, order + 1):
sizes[k] = 1 + sizes[k - 1] + sizes[k - 2]
def root_path(label):
base = 0
k = order
path = []
while True:
path.append(base)
if label == base:
return path
if k < 2:
raise ValueError("Invalid label for the given order")
left_size = sizes[k - 1]
left_root = base + 1
right_root = base + 1 + left_size
if left_root <= label < left_root + left_size:
base = left_root
k -= 1
else:
base = right_root
k -= 2
path_start = root_path(start)
path_end = root_path(end)
i = 0
limit = min(len(path_start), len(path_end))
while i < limit and path_start[i] == path_end[i]:
i += 1
return path_start[i - 1:][::-1] + path_end[i:]Time complexity: O(order). Space complexity: O(order).
Hints
- Precompute size(k). In preorder, every subtree occupies one contiguous range of labels.
- Find the path from the root to start and to end using only range checks, then combine them through their lowest common ancestor.