#1483

Kth Ancestor of a Tree Node

Hard
Binary SearchDynamic ProgrammingBit ManipulationTreeDepth-First SearchBreadth-First SearchDesignBinary LiftingDynamic Programming
LeetCode ↗

Approaches

Brute ForceOptimal
Complexity Comparison
Brute ForceOptimal Solution
Time
O(n²)
O(n log n) for preprocessing, O(log n) for each query
Space
O(1)
O(n log n)
💡

Intuition

Time O(n log n) for preprocessing, O(log n) for each querySpace O(n log n)

Using a sparse table approach allows us to precompute ancestors at different powers of two, enabling us to jump up the tree in logarithmic steps. This drastically reduces the time complexity for each query.

⚙️

Algorithm

3 steps
  1. 1Step 1: Precompute a table where table[i][j] represents the 2^j-th ancestor of node i.
  2. 2Step 2: For each query, use the precomputed table to find the k-th ancestor by breaking k down into powers of two.
  3. 3Step 3: If at any point the ancestor does not exist, return -1.
solution.py20 lines
1class TreeAncestor:
2    def __init__(self, n: int, parent: List[int]):
3        self.log = 1
4        while (1 << self.log) <= n:
5            self.log += 1
6        self.ancestor = [[-1] * self.log for _ in range(n)]
7        for i in range(n):
8            self.ancestor[i][0] = parent[i]
9        for j in range(1, self.log):
10            for i in range(n):
11                if self.ancestor[i][j - 1] != -1:
12                    self.ancestor[i][j] = self.ancestor[self.ancestor[i][j - 1]][j - 1]
13                
14    def getKthAncestor(self, node: int, k: int) -> int:
15        for j in range(self.log):
16            if k & (1 << j):
17                node = self.ancestor[node][j]
18                if node == -1:
19                    return -1
20        return node

Complexity note: The preprocessing step takes O(n log n) due to filling the ancestor table, while each query takes O(log n) because we can jump through the tree in logarithmic steps.

  • 1Using a sparse table allows for efficient ancestor retrieval by leveraging binary lifting.
  • 2Understanding how to break down k into powers of two is crucial for optimizing the traversal.

Solutions and explanations are original Tejav content. Problem titles © LeetCode — use the LeetCode button above for the full problem statement.