Skip to main content

Command Palette

Search for a command to run...

Solving Leetcode Interviews in Seconds with AI: Kth Ancestor of a Tree Node

Updated
3 min read

Introduction

In this blog post, we will explore how to solve the LeetCode problem "1483" using AI. LeetCode is a popular platform for preparing for coding interviews, and with the help of AI tools like Chatmagic, we can generate solutions quickly and efficiently - helping you pass the interviews and get the job offer without having to study for months.

Problem Statement

You are given a tree with n nodes numbered from 0 to n - 1 in the form of a parent array parent where parent[i] is the parent of ith node. The root of the tree is node 0. Find the kth ancestor of a given node. The kth ancestor of a tree node is the kth node in the path from that node to the root node. Implement the TreeAncestor class: TreeAncestor(int n, int[] parent) Initializes the object with the number of nodes in the tree and the parent array. int getKthAncestor(int node, int k) return the kth ancestor of the given node node. If there is no such ancestor, return -1. Example 1: Input ["TreeAncestor", "getKthAncestor", "getKthAncestor", "getKthAncestor"] [[7, [-1, 0, 0, 1, 1, 2, 2]], [3, 1], [5, 2], [6, 3]] Output [null, 1, 0, -1] Explanation TreeAncestor treeAncestor = new TreeAncestor(7, [-1, 0, 0, 1, 1, 2, 2]); treeAncestor.getKthAncestor(3, 1); // returns 1 which is the parent of 3 treeAncestor.getKthAncestor(5, 2); // returns 0 which is the grandparent of 5 treeAncestor.getKthAncestor(6, 3); // returns -1 because there is no such ancestor Constraints: 1 <= k <= n <= 5 104 parent.length == n parent[0] == -1 0 <= parent[i] < n for all 0 < i < n 0 <= node < n There will be at most 5 104 queries.

Explanation

Here's the solution to find the kth ancestor of a node in a tree, along with an explanation of the approach, complexity analysis, and the Python code.

  • Binary Lifting: The core idea is to precompute the 2i-th ancestor for each node. This is done using dynamic programming. We store these ancestors in a 2D array ancestors, where ancestors[node][i] represents the 2i-th ancestor of node.

  • Efficient Querying: To find the k-th ancestor of a node, we decompose k into its binary representation. For each bit set in k, we "jump" to the corresponding precomputed ancestor. This allows us to find the k-th ancestor in logarithmic time.

  • Initialization: The ancestors array is initialized using the parent array. ancestors[node][0] is simply the parent of the node. The remaining entries are computed iteratively: ancestors[node][i] = ancestors[ancestors[node][i-1]][i-1]. This means the 2i-th ancestor of node is the 2(i-1)-th ancestor of the 2(i-1)-th ancestor of node.

  • Runtime & Storage Complexity:

    • Time Complexity: Initialization: O(n log n), Query: O(log k) ≈ O(log n) since k <= n.
    • Space Complexity: O(n log n) for the ancestors array.

Code

    class TreeAncestor:

    def __init__(self, n: int, parent: list[int]):
        self.n = n
        self.max_level = n.bit_length()  # ceil(log2(n)) + 1
        self.ancestors = [[-1] * self.max_level for _ in range(n)]

        for i in range(n):
            self.ancestors[i][0] = parent[i]

        for j in range(1, self.max_level):
            for i in range(n):
                if self.ancestors[i][j-1] != -1:
                    self.ancestors[i][j] = self.ancestors[self.ancestors[i][j-1]][j-1]

    def getKthAncestor(self, node: int, k: int) -> int:
        for i in range(self.max_level):
            if (k >> i) & 1:
                node = self.ancestors[node][i]
                if node == -1:
                    return -1
        return node

More from this blog

C

Chatmagic blog

2894 posts