diff --git a/solution/1400-1499/1483.Kth Ancestor of a Tree Node/README.md b/solution/1400-1499/1483.Kth Ancestor of a Tree Node/README.md index c96a6c5e176e1..89fe1cf6b6c5d 100644 --- a/solution/1400-1499/1483.Kth Ancestor of a Tree Node/README.md +++ b/solution/1400-1499/1483.Kth Ancestor of a Tree Node/README.md @@ -89,8 +89,8 @@ class TreeAncestor: self.p = [[-1] * 18 for _ in range(n)] for i, fa in enumerate(parent): self.p[i][0] = fa - for i in range(n): - for j in range(1, 18): + 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] @@ -125,8 +125,8 @@ class TreeAncestor { for (int i = 0; i < n; ++i) { p[i][0] = parent[i]; } - for (int i = 0; i < n; ++i) { - for (int j = 1; j < 18; ++j) { + for (int j = 1; j < 18; ++j) { + for (int i = 0; i < n; ++i) { if (p[i][j - 1] == -1) { continue; } @@ -165,8 +165,8 @@ public: for (int i = 0; i < n; ++i) { p[i][0] = parent[i]; } - for (int i = 0; i < n; ++i) { - for (int j = 1; j < 18; ++j) { + for (int j = 1; j < 18; ++j) { + for (int i = 0; i < n; ++i) { if (p[i][j - 1] == -1) { continue; } @@ -213,8 +213,8 @@ func Constructor(n int, parent []int) TreeAncestor { p[i][j] = -1 } } - for i := range p { - for j := 1; j < 18; j++ { + for j := 1; j < 18; j++ { + for i := range p { if p[i][j-1] == -1 { continue } @@ -246,6 +246,7 @@ func (this *TreeAncestor) GetKthAncestor(node int, k int) int { ### **TypeScript** ```ts +class TreeAncestor { class TreeAncestor { private p: number[][]; @@ -254,8 +255,8 @@ class TreeAncestor { for (let i = 0; i < n; ++i) { p[i][0] = parent[i]; } - for (let i = 0; i < n; ++i) { - for (let j = 1; j < 18; ++j) { + for (let j = 1; j < 18; ++j) { + for (let i = 0; i < n; ++i) { if (p[i][j - 1] === -1) { continue; } diff --git a/solution/1400-1499/1483.Kth Ancestor of a Tree Node/README_EN.md b/solution/1400-1499/1483.Kth Ancestor of a Tree Node/README_EN.md index 2a8ec0566bc51..288d4edd06d72 100644 --- a/solution/1400-1499/1483.Kth Ancestor of a Tree Node/README_EN.md +++ b/solution/1400-1499/1483.Kth Ancestor of a Tree Node/README_EN.md @@ -45,6 +45,28 @@ treeAncestor.getKthAncestor(6, 3); // returns -1 because there is no such ancest ## 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 $2^j$-th ancestor node of node $i$, i.e., the node reached by moving $2^j$ 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 $2^j$-th ancestor node of node $i$, we can first find the $2^{j-1}$-th ancestor node of node $i$, and then find the $2^{j-1}$-th ancestor node of this node. Therefore, we need to find the ancestor node of each node at a distance of $2^j$, 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 \times \log n)$, and the query is $O(\log n)$. The space complexity is $O(n \times \log n)$, where $n$ is the number of nodes in the tree. + +Similar problems: + +- [2836. Maximize Value of Function in a Ball Passing Game](/solution/2800-2899/2836.Maximize%20Value%20of%20Function%20in%20a%20Ball%20Passing%20Game/README_EN.md) + <!-- tabs:start --> ### **Python3** @@ -55,8 +77,8 @@ class TreeAncestor: self.p = [[-1] * 18 for _ in range(n)] for i, fa in enumerate(parent): self.p[i][0] = fa - for i in range(n): - for j in range(1, 18): + 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] @@ -89,8 +111,8 @@ class TreeAncestor { for (int i = 0; i < n; ++i) { p[i][0] = parent[i]; } - for (int i = 0; i < n; ++i) { - for (int j = 1; j < 18; ++j) { + for (int j = 1; j < 18; ++j) { + for (int i = 0; i < n; ++i) { if (p[i][j - 1] == -1) { continue; } @@ -129,8 +151,8 @@ public: for (int i = 0; i < n; ++i) { p[i][0] = parent[i]; } - for (int i = 0; i < n; ++i) { - for (int j = 1; j < 18; ++j) { + for (int j = 1; j < 18; ++j) { + for (int i = 0; i < n; ++i) { if (p[i][j - 1] == -1) { continue; } @@ -177,8 +199,8 @@ func Constructor(n int, parent []int) TreeAncestor { p[i][j] = -1 } } - for i := range p { - for j := 1; j < 18; j++ { + for j := 1; j < 18; j++ { + for i := range p { if p[i][j-1] == -1 { continue } @@ -218,8 +240,8 @@ class TreeAncestor { for (let i = 0; i < n; ++i) { p[i][0] = parent[i]; } - for (let i = 0; i < n; ++i) { - for (let j = 1; j < 18; ++j) { + for (let j = 1; j < 18; ++j) { + for (let i = 0; i < n; ++i) { if (p[i][j - 1] === -1) { continue; } diff --git a/solution/1400-1499/1483.Kth Ancestor of a Tree Node/Solution.cpp b/solution/1400-1499/1483.Kth Ancestor of a Tree Node/Solution.cpp index 1e742da970f3f..1197bbe436e55 100644 --- a/solution/1400-1499/1483.Kth Ancestor of a Tree Node/Solution.cpp +++ b/solution/1400-1499/1483.Kth Ancestor of a Tree Node/Solution.cpp @@ -5,8 +5,8 @@ class TreeAncestor { for (int i = 0; i < n; ++i) { p[i][0] = parent[i]; } - for (int i = 0; i < n; ++i) { - for (int j = 1; j < 18; ++j) { + for (int j = 1; j < 18; ++j) { + for (int i = 0; i < n; ++i) { if (p[i][j - 1] == -1) { continue; } @@ -35,4 +35,4 @@ class TreeAncestor { * Your TreeAncestor object will be instantiated and called as such: * TreeAncestor* obj = new TreeAncestor(n, parent); * int param_1 = obj->getKthAncestor(node,k); - */ \ No newline at end of file + */ diff --git a/solution/1400-1499/1483.Kth Ancestor of a Tree Node/Solution.go b/solution/1400-1499/1483.Kth Ancestor of a Tree Node/Solution.go index da0d002091622..04f04ede95880 100644 --- a/solution/1400-1499/1483.Kth Ancestor of a Tree Node/Solution.go +++ b/solution/1400-1499/1483.Kth Ancestor of a Tree Node/Solution.go @@ -10,8 +10,8 @@ func Constructor(n int, parent []int) TreeAncestor { p[i][j] = -1 } } - for i := range p { - for j := 1; j < 18; j++ { + for j := 1; j < 18; j++ { + for i := range p { if p[i][j-1] == -1 { continue } @@ -37,4 +37,4 @@ func (this *TreeAncestor) GetKthAncestor(node int, k int) int { * Your TreeAncestor object will be instantiated and called as such: * obj := Constructor(n, parent); * param_1 := obj.GetKthAncestor(node,k); - */ \ No newline at end of file + */ diff --git a/solution/1400-1499/1483.Kth Ancestor of a Tree Node/Solution.java b/solution/1400-1499/1483.Kth Ancestor of a Tree Node/Solution.java index 059aa2e31e46b..fb9ccca670a93 100644 --- a/solution/1400-1499/1483.Kth Ancestor of a Tree Node/Solution.java +++ b/solution/1400-1499/1483.Kth Ancestor of a Tree Node/Solution.java @@ -9,8 +9,8 @@ public TreeAncestor(int n, int[] parent) { for (int i = 0; i < n; ++i) { p[i][0] = parent[i]; } - for (int i = 0; i < n; ++i) { - for (int j = 1; j < 18; ++j) { + for (int j = 1; j < 18; ++j) { + for (int i = 0; i < n; ++i) { if (p[i][j - 1] == -1) { continue; } @@ -36,4 +36,4 @@ public int getKthAncestor(int node, int k) { * Your TreeAncestor object will be instantiated and called as such: * TreeAncestor obj = new TreeAncestor(n, parent); * int param_1 = obj.getKthAncestor(node,k); - */ \ No newline at end of file + */ diff --git a/solution/1400-1499/1483.Kth Ancestor of a Tree Node/Solution.py b/solution/1400-1499/1483.Kth Ancestor of a Tree Node/Solution.py index 708d6d0d0ca03..2f52c4dcc3b86 100644 --- a/solution/1400-1499/1483.Kth Ancestor of a Tree Node/Solution.py +++ b/solution/1400-1499/1483.Kth Ancestor of a Tree Node/Solution.py @@ -3,8 +3,8 @@ 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 i in range(n): - for j in range(1, 18): + 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] diff --git a/solution/1400-1499/1483.Kth Ancestor of a Tree Node/Solution.ts b/solution/1400-1499/1483.Kth Ancestor of a Tree Node/Solution.ts index 2805876c5e50f..9f704a1ddccaa 100644 --- a/solution/1400-1499/1483.Kth Ancestor of a Tree Node/Solution.ts +++ b/solution/1400-1499/1483.Kth Ancestor of a Tree Node/Solution.ts @@ -6,8 +6,8 @@ class TreeAncestor { for (let i = 0; i < n; ++i) { p[i][0] = parent[i]; } - for (let i = 0; i < n; ++i) { - for (let j = 1; j < 18; ++j) { + for (let j = 1; j < 18; ++j) { + for (let i = 0; i < n; ++i) { if (p[i][j - 1] === -1) { continue; }