亚马逊 在线测试题目 amazon (变种的)三叉树的最近公共祖先问题

题目意思就是找一棵按上面链接所示的树对应的上面的两个点的最小公共祖先(LCP,Least Common Father),按照比较大小来依次返回自己的父亲节点就行了。具体看代码:getfather(a)函数是找父亲的代码

#include <cstdio>  
#include <cstring>  
#include <iostream>  
#include <algorithm>  
using namespace std;  
const int maxDepth = 21; 
long long three[maxDepth] , sum[maxDepth];  
void init() {   
    three[0] = 1;  
    sum[0] = 0;  
    for(int i=1;i<maxDepth;i++)
    {   
        three[i] = three[i-1] * 3 ; 
        sum[i] = sum[i-1] + three[i];  
    }   

    for(int i = 0; i < maxDepth; i ++) 
    {   
        cout << three[i] << "	";
    }   
    cout << endl;

    for(int i = 0; i < maxDepth; i ++) 
    {   
        cout << sum[i] << "	";
    }   
    cout << endl;
    //cout << "INT_MAX	" << INT_MAX <<endl;
}  
int getfather(long long a) {   
    if(a <= 3)
        return 0;  
    int i;  
    for(i=0;sum[i]<a;i++)
        ;
    i-- ;
    int tmp = (2+a-sum[i]) /3;
    int father = sum[i] - tmp + 1;
    return father;
}
int LCP(int a,int b) {
    while(a != b) {
        if(a > b) a = getfather(a);
        else b = getfather(b);
    }
    return a;
}
int main() {
    int a , b;
    init();
    while(scanf("%d%d" , &a,&b) != EOF) {
        //cnt = 0;  
        int ans = LCP(a , b);
        printf("%d
" , ans);
    }
    return 0;
}

其中 three array 保存3的指数
sum arry 保存截止到某一行为止,保存的数目-1,因为index是从0开始。

可以看见,sum[20] > INT_MAX 了,所以,sum中只要21个元素就能覆盖所有的 0 到 INT_MAX

同时,由于three[20]和sum[20] > INT_MAX,所以用long long 来保存。

three array:
1       3       9       27      81      243     729     2187    6561    19683   59049   177147  531441  1594323 4782969 1434890743046721        129140163       387420489       1162261467      3486784401
sum array:
0       3       12      39      120     363     1092    3279    9840    29523   88572   265719  797160  2391483 7174452 2152335964570080        193710243       581130732       1743392199      5230176600
INT_MAX 214748364

最后,交替计算当前节点的父节点,知道两者的父节点相同为止。

getFather 的计算也比较简单,和sum array 比较,找到sum[i] > node, 然后i--,知道,节点处于行的上一行。

然后计算offerset=(node-sum[i]+2)/3 就是其距离sum[i]的偏移量,所以father= sum[i]-offerset + 1;

举例:如要查找17的father,查找到 12 < 17 < 39, 所以17 处于sum[2]= 12 的下一行。

offset = (17+2 - 12) /3 = 2, 也就是说 17 的father 距离 sum[2]有两个距离。实际上是一个,

所以father = sum[2]-offset + 1 = 12 -2 + 1 = 11.

原文地址:https://www.cnblogs.com/diegodu/p/4660860.html