树节点的第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;
    }
};
posted @ 2023-06-12 00:25  失控D大白兔  阅读(19)  评论(0编辑  收藏  举报