算法思路:

对于完全二叉树,可以使用数组来存储,假设当前要求i和j的最近公共祖先,可以先求出它们的深度,然后将深度较深的节点上移,直到它们在同一层,然后同时上移,直到它们重合,此时重合的位置就是它们的最近公共祖先。

具体实现上,可以先求出i和j的深度,然后将深度较深的节点先向上移动到与深度较浅的节点同一层,然后同时向上移动,直到它们重合。每次移动时,可以通过左右子树节点数量的关系来判断往哪个方向移动。

算法实现:

#include <stdio.h>

// 求节点的深度
int depth(int i) {
    int d = 0;
    while (i > 1) {
        i /= 2;
        d++;
    }
    return d;
}

// 求公共祖先
int lca(int A[], int n, int i, int j) {
    int di = depth(i), dj = depth(j);
    // 将深度较深的节点上移
    while (di > dj) {
        i /= 2;
        di--;
    }
    while (dj > di) {
        j /= 2;
        dj--;
    }
    // 同时上移,直到重合
    while (i != j) {
        i /= 2;
        j /= 2;
    }
    return A[i];
}

int main() {
    int A[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
    int n = 15;
    int i = 4, j = 7;
    int pos = lca(A, n, i, j);
    printf("The position of LCA is %d, the value is %d\n", pos, A[pos]);
    return 0;
}

时间复杂度分析:

深度的计算需要O(logn)的时间,求公共祖先需要O(logn)的时间,因此总时间复杂度为O(logn)。

空间复杂度分析:

只需要使用常数个额外变量,因此空间复杂度为O(1)


原文地址: https://www.cveoy.top/t/topic/dxBG 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录