Skip to content

Commit 4f92772

Browse files
fix: update solution to lc problem: No.1483 (#2214)
No.1483.Kth Ancestor of a Tree Node Co-authored-by: Libin YANG <contact@yanglibin.info>
1 parent bfa5a71 commit 4f92772

File tree

7 files changed

+56
-33
lines changed

7 files changed

+56
-33
lines changed

solution/1400-1499/1483.Kth Ancestor of a Tree Node/README.md

+11-10
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,8 @@ class TreeAncestor:
8989
self.p = [[-1] * 18 for _ in range(n)]
9090
for i, fa in enumerate(parent):
9191
self.p[i][0] = fa
92-
for i in range(n):
93-
for j in range(1, 18):
92+
for j in range(1, 18):
93+
for i in range(n):
9494
if self.p[i][j - 1] == -1:
9595
continue
9696
self.p[i][j] = self.p[self.p[i][j - 1]][j - 1]
@@ -125,8 +125,8 @@ class TreeAncestor {
125125
for (int i = 0; i < n; ++i) {
126126
p[i][0] = parent[i];
127127
}
128-
for (int i = 0; i < n; ++i) {
129-
for (int j = 1; j < 18; ++j) {
128+
for (int j = 1; j < 18; ++j) {
129+
for (int i = 0; i < n; ++i) {
130130
if (p[i][j - 1] == -1) {
131131
continue;
132132
}
@@ -165,8 +165,8 @@ public:
165165
for (int i = 0; i < n; ++i) {
166166
p[i][0] = parent[i];
167167
}
168-
for (int i = 0; i < n; ++i) {
169-
for (int j = 1; j < 18; ++j) {
168+
for (int j = 1; j < 18; ++j) {
169+
for (int i = 0; i < n; ++i) {
170170
if (p[i][j - 1] == -1) {
171171
continue;
172172
}
@@ -213,8 +213,8 @@ func Constructor(n int, parent []int) TreeAncestor {
213213
p[i][j] = -1
214214
}
215215
}
216-
for i := range p {
217-
for j := 1; j < 18; j++ {
216+
for j := 1; j < 18; j++ {
217+
for i := range p {
218218
if p[i][j-1] == -1 {
219219
continue
220220
}
@@ -246,6 +246,7 @@ func (this *TreeAncestor) GetKthAncestor(node int, k int) int {
246246
### **TypeScript**
247247

248248
```ts
249+
class TreeAncestor {
249250
class TreeAncestor {
250251
private p: number[][];
251252

@@ -254,8 +255,8 @@ class TreeAncestor {
254255
for (let i = 0; i < n; ++i) {
255256
p[i][0] = parent[i];
256257
}
257-
for (let i = 0; i < n; ++i) {
258-
for (let j = 1; j < 18; ++j) {
258+
for (let j = 1; j < 18; ++j) {
259+
for (let i = 0; i < n; ++i) {
259260
if (p[i][j - 1] === -1) {
260261
continue;
261262
}

solution/1400-1499/1483.Kth Ancestor of a Tree Node/README_EN.md

+32-10
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,28 @@ treeAncestor.getKthAncestor(6, 3); // returns -1 because there is no such ancest
4545

4646
## Solutions
4747

48+
**Solution 1: Dynamic Programming + Binary Lifting**
49+
50+
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.
51+
52+
We can use dynamic programming combined with the idea of binary lifting to handle this.
53+
54+
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:
55+
56+
$$
57+
p[i][j] = p[p[i][j-1]][j-1]
58+
$$
59+
60+
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.
61+
62+
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$.
63+
64+
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.
65+
66+
Similar problems:
67+
68+
- [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)
69+
4870
<!-- tabs:start -->
4971

5072
### **Python3**
@@ -55,8 +77,8 @@ class TreeAncestor:
5577
self.p = [[-1] * 18 for _ in range(n)]
5678
for i, fa in enumerate(parent):
5779
self.p[i][0] = fa
58-
for i in range(n):
59-
for j in range(1, 18):
80+
for j in range(1, 18):
81+
for i in range(n):
6082
if self.p[i][j - 1] == -1:
6183
continue
6284
self.p[i][j] = self.p[self.p[i][j - 1]][j - 1]
@@ -89,8 +111,8 @@ class TreeAncestor {
89111
for (int i = 0; i < n; ++i) {
90112
p[i][0] = parent[i];
91113
}
92-
for (int i = 0; i < n; ++i) {
93-
for (int j = 1; j < 18; ++j) {
114+
for (int j = 1; j < 18; ++j) {
115+
for (int i = 0; i < n; ++i) {
94116
if (p[i][j - 1] == -1) {
95117
continue;
96118
}
@@ -129,8 +151,8 @@ public:
129151
for (int i = 0; i < n; ++i) {
130152
p[i][0] = parent[i];
131153
}
132-
for (int i = 0; i < n; ++i) {
133-
for (int j = 1; j < 18; ++j) {
154+
for (int j = 1; j < 18; ++j) {
155+
for (int i = 0; i < n; ++i) {
134156
if (p[i][j - 1] == -1) {
135157
continue;
136158
}
@@ -177,8 +199,8 @@ func Constructor(n int, parent []int) TreeAncestor {
177199
p[i][j] = -1
178200
}
179201
}
180-
for i := range p {
181-
for j := 1; j < 18; j++ {
202+
for j := 1; j < 18; j++ {
203+
for i := range p {
182204
if p[i][j-1] == -1 {
183205
continue
184206
}
@@ -218,8 +240,8 @@ class TreeAncestor {
218240
for (let i = 0; i < n; ++i) {
219241
p[i][0] = parent[i];
220242
}
221-
for (let i = 0; i < n; ++i) {
222-
for (let j = 1; j < 18; ++j) {
243+
for (let j = 1; j < 18; ++j) {
244+
for (let i = 0; i < n; ++i) {
223245
if (p[i][j - 1] === -1) {
224246
continue;
225247
}

solution/1400-1499/1483.Kth Ancestor of a Tree Node/Solution.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ class TreeAncestor {
55
for (int i = 0; i < n; ++i) {
66
p[i][0] = parent[i];
77
}
8-
for (int i = 0; i < n; ++i) {
9-
for (int j = 1; j < 18; ++j) {
8+
for (int j = 1; j < 18; ++j) {
9+
for (int i = 0; i < n; ++i) {
1010
if (p[i][j - 1] == -1) {
1111
continue;
1212
}
@@ -35,4 +35,4 @@ class TreeAncestor {
3535
* Your TreeAncestor object will be instantiated and called as such:
3636
* TreeAncestor* obj = new TreeAncestor(n, parent);
3737
* int param_1 = obj->getKthAncestor(node,k);
38-
*/
38+
*/

solution/1400-1499/1483.Kth Ancestor of a Tree Node/Solution.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ func Constructor(n int, parent []int) TreeAncestor {
1010
p[i][j] = -1
1111
}
1212
}
13-
for i := range p {
14-
for j := 1; j < 18; j++ {
13+
for j := 1; j < 18; j++ {
14+
for i := range p {
1515
if p[i][j-1] == -1 {
1616
continue
1717
}
@@ -37,4 +37,4 @@ func (this *TreeAncestor) GetKthAncestor(node int, k int) int {
3737
* Your TreeAncestor object will be instantiated and called as such:
3838
* obj := Constructor(n, parent);
3939
* param_1 := obj.GetKthAncestor(node,k);
40-
*/
40+
*/

solution/1400-1499/1483.Kth Ancestor of a Tree Node/Solution.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ public TreeAncestor(int n, int[] parent) {
99
for (int i = 0; i < n; ++i) {
1010
p[i][0] = parent[i];
1111
}
12-
for (int i = 0; i < n; ++i) {
13-
for (int j = 1; j < 18; ++j) {
12+
for (int j = 1; j < 18; ++j) {
13+
for (int i = 0; i < n; ++i) {
1414
if (p[i][j - 1] == -1) {
1515
continue;
1616
}
@@ -36,4 +36,4 @@ public int getKthAncestor(int node, int k) {
3636
* Your TreeAncestor object will be instantiated and called as such:
3737
* TreeAncestor obj = new TreeAncestor(n, parent);
3838
* int param_1 = obj.getKthAncestor(node,k);
39-
*/
39+
*/

solution/1400-1499/1483.Kth Ancestor of a Tree Node/Solution.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ def __init__(self, n: int, parent: List[int]):
33
self.p = [[-1] * 18 for _ in range(n)]
44
for i, fa in enumerate(parent):
55
self.p[i][0] = fa
6-
for i in range(n):
7-
for j in range(1, 18):
6+
for j in range(1, 18):
7+
for i in range(n):
88
if self.p[i][j - 1] == -1:
99
continue
1010
self.p[i][j] = self.p[self.p[i][j - 1]][j - 1]

solution/1400-1499/1483.Kth Ancestor of a Tree Node/Solution.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ class TreeAncestor {
66
for (let i = 0; i < n; ++i) {
77
p[i][0] = parent[i];
88
}
9-
for (let i = 0; i < n; ++i) {
10-
for (let j = 1; j < 18; ++j) {
9+
for (let j = 1; j < 18; ++j) {
10+
for (let i = 0; i < n; ++i) {
1111
if (p[i][j - 1] === -1) {
1212
continue;
1313
}

0 commit comments

Comments
 (0)