PracHub
QuestionsPremiumCoachesLearningGuidesInterview Prep

Quick Overview

This question evaluates understanding of recursion, tree traversal, implicit data structures, and index arithmetic for navigating preorder-numbered Fibonacci trees and computing node-to-node paths.

  • hard
  • Databricks
  • Coding & Algorithms
  • Software Engineer

Find path in implicit Fibonacci tree

Company: Databricks

Role: Software Engineer

Category: Coding & Algorithms

Difficulty: hard

Interview Round: Onsite

You are given a special family of binary trees called **Fibonacci trees**. The `k`‑th order Fibonacci tree `T(k)` is defined recursively: - `T(1)` is a single node. - `T(2)` is a single node. - For `k ≥ 3`, `T(k)` is a tree whose root has: - left subtree `T(k − 1)` and - right subtree `T(k − 2)`. Let `size(k)` be the number of nodes in `T(k)`. You can compute `size(k)` from the definition above: - `size(1) = 1` - `size(2) = 1` - `size(k) = 1 + size(k − 1) + size(k − 2)` for `k ≥ 3` Now, imagine we **number** the nodes of `T(k)` in **preorder** (root, then left subtree, then right subtree), using **1‑based indices** from `1` to `size(k)`. You are given: - An integer `k` (the order of the Fibonacci tree), with `1 ≤ k ≤ 60`. - Two integers `a` and `b`, such that `1 ≤ a, b ≤ size(k)`; these are **indices** of two nodes in the preorder numbering of `T(k)`. The tree can be **very large** for big `k`, so you **must not** construct it explicitly in memory. ### Task Design and implement a function: ```text List<Long> pathInFibonacciTree(long k, long a, long b) ``` that returns the **sequence of node indices** (in preorder numbering) along the simple path from node `a` to node `b` in `T(k)`. - The path should start with `a` and end with `b`. - Indices in the returned list should be the preorder indices in `T(k)`. Constraints and requirements: - `k` can be as large as 60 (or similar), so `size(k)` may be large (up to around 10^12). Use 64‑bit integers for sizes and indices. - You must treat the tree **implicitly**: - Use the recursive structure and the sizes of subtrees to navigate. - You may not allocate `O(size(k))` memory or explicitly build all nodes. - Aim for an algorithm with time complexity **polylogarithmic or at worst O(h)**, where `h` is the height of the tree (proportional to `k`), i.e., `O(k)` or similar. ### Hints / clarifications - Because of the preorder layout, for `T(k)`: - The root always has index `1` in its own tree. - The left subtree `T(k − 1)` occupies indices `[2, 1 + size(k − 1)]` in `T(k)`. - The right subtree `T(k − 2)` occupies the following range after that. - You may find it helpful to implement helper functions that, given `(k, indexRange, nodeIndex)`, determine whether the node lies in the left subtree, right subtree, or is the root. Design your algorithm and helper functions so that you can: 1. Compute the path from each node up to the root (in terms of indices) without building the tree. 2. Combine these paths to construct the path from `a` to `b` via their lowest common ancestor (LCA). Return the final path as a list of preorder indices.

Quick Answer: This question evaluates understanding of recursion, tree traversal, implicit data structures, and index arithmetic for navigating preorder-numbered Fibonacci trees and computing node-to-node paths.

A Fibonacci tree T(k) is defined recursively: T(1) and T(2) each contain a single node, and for k >= 3 the root of T(k) has left subtree T(k - 1) and right subtree T(k - 2). Let size(1) = 1, size(2) = 1, and size(k) = 1 + size(k - 1) + size(k - 2). Nodes of T(k) are numbered in preorder starting from 1. Given k and two preorder indices a and b, return the sequence of preorder indices along the unique simple path from node a to node b. The tree can be enormous, so you must solve it without explicitly constructing all nodes.

Constraints

  • 1 <= k <= 60
  • 1 <= a, b <= size(k)
  • Do not build the full tree explicitly; use its recursive structure and subtree sizes

Examples

Input: (1, 1, 1)

Expected Output: [1]

Explanation: T(1) has only one node, so the path from 1 to 1 is just [1].

Input: (4, 3, 5)

Expected Output: [3, 2, 1, 5]

Explanation: In T(4), node 3 is under the left subtree and node 5 is the right child of the root, so the path goes 3 -> 2 -> 1 -> 5.

Input: (5, 4, 5)

Expected Output: [4, 3, 5]

Explanation: In T(5), nodes 4 and 5 are the two children of node 3, so the path is 4 -> 3 -> 5.

Input: (5, 1, 9)

Expected Output: [1, 7, 9]

Explanation: Node 1 is the root. Node 9 lies in the right subtree rooted at 7, so the path is 1 -> 7 -> 9.

Input: (6, 7, 14)

Expected Output: [7, 3, 2, 1, 11, 12, 14]

Explanation: Node 7 is in the left subtree of the root, while 14 is in the right subtree. Their lowest common ancestor is 1.

Input: (6, 10, 10)

Expected Output: [10]

Explanation: When both endpoints are the same node, the path contains only that node.

Input: (8, 1, 41)

Expected Output: [1, 27, 37, 41]

Explanation: In T(8), the path from the root to the last preorder index follows the right subtree roots 27 and 37, then reaches 41.

Solution

def solution(k, a, b):
    max_k = max(2, k)
    sizes = [0] * (max_k + 1)
    sizes[1] = 1
    sizes[2] = 1
    for i in range(3, k + 1):
        sizes[i] = 1 + sizes[i - 1] + sizes[i - 2]

    def path_to_root(order, target):
        root = 1
        ancestors = []

        while target != root:
            ancestors.append(root)
            left_size = sizes[order - 1]
            left_root = root + 1
            left_end = root + left_size

            if left_root <= target <= left_end:
                root = left_root
                order -= 1
            else:
                root = root + 1 + left_size
                order -= 2

        return [target] + ancestors[::-1]

    path_a = path_to_root(k, a)
    path_b = path_to_root(k, b)

    i = len(path_a) - 1
    j = len(path_b) - 1
    while i >= 0 and j >= 0 and path_a[i] == path_b[j]:
        i -= 1
        j -= 1

    return path_a[:i + 2] + path_b[:j + 1][::-1]

Time complexity: O(k). Space complexity: O(k).

Hints

  1. For a subtree T(t) rooted at global index r, the left subtree root is at r + 1 and occupies indices [r + 1, r + size(t - 1)]. The right subtree starts immediately after that block.
  2. Compute the path from each target node up to the root using only index ranges. Then find the lowest common ancestor by comparing the two rootward paths from the end.
Last updated: Apr 19, 2026

Loading coding console...

PracHub

Master your tech interviews with 8,500+ real questions from top companies.

Product

  • Questions
  • Learning Tracks
  • Interview Guides
  • Resources
  • Premium
  • For Universities
  • Student Access

Browse

  • By Company
  • By Role
  • By Category
  • Topic Hubs
  • SQL Questions
  • Compare Platforms
  • Discord Community

Support

  • support@prachub.com
  • (916) 541-4762

Legal

  • Privacy Policy
  • Terms of Service
  • About Us

© 2026 PracHub. All rights reserved.

Related Coding Questions

  • Implement a Snapshot Set Iterator - Databricks (medium)
  • Find the Best Commute Mode - Databricks (medium)
  • Partition a Target String by Source Substrings - Databricks (medium)
  • Design In-Memory QPS Counter - Databricks (medium)
  • Implement Random Connectivity and Grid Routing - Databricks