LeetCode 1483. Kth Ancestor of a Tree Node Solution in Java, C++, Python & More | Explanation + Code

CoderIndeed
0
1483. Kth Ancestor of a Tree Node

Description

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.

Solutions

Solution 1: Dynamic Programming + Binary Lifting

The problem asks us to find the k-th ancestor node of a node node. If we solve it by brute force, we need to traverse upwards from node for k times, which has a time complexity of O(k) and will obviously exceed the time limit.

We can use dynamic programming combined with the idea of binary lifting to handle this.

We define p[i][j] as the 2j-th ancestor node of node i, i.e., the node reached by moving 2j steps upwards from node i. Then we can get the state transition equation:

p[i][j] = p[p[i][j-1]][j-1]

That is, to find the 2j-th ancestor node of node i, we can first find the 2j-1-th ancestor node of node i, and then find the 2j-1-th ancestor node of this node. Therefore, we need to find the ancestor node of each node at a distance of 2j, until we reach the maximum height of the tree.

For each query later, we can decompose k into its binary representation, and then according to the positions of 1 in the binary, we accumulate the queries upwards, and finally get the k-th ancestor node of node node.

In terms of time complexity, the initialization is O(n × log n), and the query is O(log n). The space complexity is O(n × log n), where n is the number of nodes in the tree.

Similar problems:

PythonJavaC++GoTypeScriptC#
class TreeAncestor: def __init__(self, n: int, parent: List[int]): self.p = [[-1] * 18 for _ in range(n)] for i, fa in enumerate(parent): self.p[i][0] = fa for j in range(1, 18): for i in range(n): if self.p[i][j - 1] == -1: continue self.p[i][j] = self.p[self.p[i][j - 1]][j - 1] def getKthAncestor(self, node: int, k: int) -> int: for i in range(17, -1, -1): if k >> i & 1: node = self.p[node][i] if node == -1: break return node # Your TreeAncestor object will be instantiated and called as such: # obj = TreeAncestor(n, parent) # param_1 = obj.getKthAncestor(node,k)(code-box)

Post a Comment

0Comments

Post a Comment (0)

#buttons=(Accept !) #days=(20)

Our website uses cookies to enhance your experience. Check Now
Accept !