树节点的第K个祖先
给你一棵树,树上有 n 个节点,按从 0 到 n-1 编号。树以父节点数组的形式给出
其中 parent[i] 是节点 i 的父节点。树的根节点是编号为 0 的节点。
树节点的第 k 个祖先节点是从该节点到根节点路径上的第 k 个节点
返回数的第k个祖先节点,如果不存在返回-1
1. 倍增查找(类似快速幂)
线性查找超时,考虑以指数的形式存储所有元素的祖先,使时间复杂度为对数级别
class TreeAncestor {
public:
vector<vector<int>> ancestors;
TreeAncestor(int n, vector<int>& parent) {
ancestors.resize(n,vector<int>(16,-1));
for(int i =0;i<n;i++)
ancestors[i][0] = parent[i];//初始化第一个祖先
for(int j=1;j<16;j++){//倍增赋值
for(int i=0;i<n;i++){//遍历所有元素
if(ancestors[i][j-1]!=-1){//可以由上一指数传递
int ancestor = ancestors[i][j-1];//上一级数的祖先
ancestors[i][j] = ancestors[ancestor][j-1];//祖先的祖先赋给下一级数
}
}
}
}
int getKthAncestor(int node, int k) {
for(int i=0;i<16;i++){//类似快速幂,提取每一个级数应该转移的位置
if((k>>i)&1){
node = ancestors[node][i];
if(node==-1) return -1;
}
}
return node;
}
};