CC191 最近公共祖先

链接CC191 最近公共祖先

描述

将一棵无穷大满二叉树的结点按根结点一层一层地从左往右编号,根结点编号为1。现给定a,b为两个结点。设计一个算法,返回a、b最近的公共祖先的编号。注意其祖先也可能是结点本身。

分析

分析题目可知,是对满二叉树进行层序遍历,根据a,b两个节点序号,找其最近的父节点的编号。 这个问题,目前想到了两种解决方法:利用二叉堆的性质、利用位运算和二叉树性质

方法1 利用二叉堆的性质

详细思路:满二叉树的子节点与父节点之间的关系为root = child / 2 利用这个关系,如果a != b,就让其中的较大数除以2, 如此循环知道a == b, 此时a或b的值,即是原来两个数的最近公共祖先的序号 代码如下: class LCA {
public:
int getLCA(int a, int b) {
// write code here
while(a != b)
{
if(a > b)
a /= 2;
else
b /= 2;
}
return a;
}
};

方法2 利用位运算和二叉树性质

脑子里根据题目描述想象一颗这样的二叉树,所有的子树都是满的,从根节点出发,每层从左到右,依次给每个节点一个递增的序号。然后上面每个编号转化成二进制,就会发现,每个节点A的2个儿子节点的二进制表示,是A的二进制表示后分别追加0和1.

于是一种不需要任何数据结构的思路是,把序号从10进制数转化成二进制串,从高位到低位,找最长公共前缀,这个前缀转化成十进制int就行了。 如果二叉树向下发展,就是index2+0, index2+1,在二进制形式上就是末尾添0和1,所以有公共祖先的一定有公共子串(二进制) class LCA { public: string int2b(int x){ string ans=""; while(x){ ans=(char)((x&1)+'0')+ans; x/=2; } return ans; } int getLCA(int a, int b) { string sa=int2b(a); string sb=int2b(b); int ans=0; for(int i=0;i<sa.length()&&i<sb.length();i++){ if(sa[i]==sb[i]) ans=ans*2+(sa[i]-'0'); else break; } return ans; } };

总结

解决问题,要充分利用其本身的性质。

全部评论

相关推荐

最近又搬回宿舍了,在工位坐不住,写一写秋招起伏不断的心态变化,也算对自己心态的一些思考表演式学习从开始为实习准备的时候就特别焦虑,楼主一开始选择的是cpp后端,但是24届这个方向已经炸了,同时自己又因为本科非92且非科班,所以感到机会更加迷茫。在某天晚上用java写出hello&nbsp;world并失眠一整晚后选择老本行干嵌入式。理想是美好的,现实情况是每天忙但又没有实质性进展,总是在配环境,调工具,顺带还要推科研。而这时候才发现自己一直在表演式学习,徘徊在设想如何展开工作的循环里,导致没有实质性进展。现在看来当时如果把精力专注在动手写而不是两只手端着看教程,基本功或许不会那么差。实习的焦虑5月,楼主...
耶比:哲学上有一个问题,玛丽的房间:玛丽知道眼睛识别色彩的原理知道各种颜色,但是她生活在黑白的房间里,直到有一天玛丽的房门打开了她亲眼看到了颜色,才知道什么是色彩。我现在最大可能的减少对非工作事情的思考,如果有一件事困扰了我, 能解决的我就直接做(去哪里或者和谁吵架等等……),解决不了的我就不想了,每一天都是最年轻的一天,珍惜今天吧
投递比亚迪等公司10个岗位 > 秋招被确诊为…… 牛客创作赏金赛
点赞 评论 收藏
分享
专心打鱼:互联网搬运工,贴子都要偷
点赞 评论 收藏
分享
Yushuu:你的确很厉害,但是有一个小问题:谁问你了?我的意思是,谁在意?我告诉你,根本没人问你,在我们之中0人问了你,我把所有问你的人都请来 party 了,到场人数是0个人,誰问你了?WHO ASKED?谁问汝矣?誰があなたに聞きましたか?누가 물어봤어?我爬上了珠穆朗玛峰也没找到谁问你了,我刚刚潜入了世界上最大的射电望远镜也没开到那个问你的人的盒,在找到谁问你之前我连癌症的解药都发明了出来,我开了最大距离渲染也没找到谁问你了我活在这个被辐射蹂躏了多年的破碎世界的坟墓里目睹全球核战争把人类文明毁灭也没见到谁问你了😆
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务