巧用深度优先遍历(DFS)查找两个结点的最近公共祖先

巧用深度优先遍历(DFS)查找两个结点的最近祖先

今天在论坛上看到一个问题:已知一棵链式存储的二叉树上的两个结点p、q,求解如何快速找到他们的公共祖先。

   说实话,我的第一个念头就是吐槽为什么不用数组存储二叉树呢?那样的话只要分别读这两个结点所在位置,然后模仿辗转相除/相减的运算方法不断把比较大的那个数字整除2,直到两个数相等位置,相等的那个数字就是p、q的最近祖先了。

回到问题本身,现实状况就是这课二叉树现成就是用链表存储的,总不能为了找 最近祖先 就把链表转换成数组吧,太费力了。

   我想到的最直接的方式就是分别输出p和q的路径,然后从前往后逐个比较判断是否一致,每一个一致的都是p和q的公共祖先,最近公共祖先自然就是最后一个满足条件的咯!

这个方法相当费力,需要先递归遍历找到p、q,再向上递归输出路径。时空复杂度都很高。所以二话不说我就用上百度了。
受划线处启发
可惜词条语焉不详,我的知识程度也很有限完全理解不了那些伪代码的含义思路。不过受划线处那句话启发,我突然发现,其实执行一次遍历就可以分别经过结点p、q以及他们的所有祖先。
下面结合网上随手下的一棵二叉树(图T-1)谈谈我的思路。
T-1
Test1:寻找4和13的最近公共祖先

   -使用DFS遍历当我们来到13的时候发现第一个我们要寻找的结点,初始化temp{一个用于保存祖先信息的缓存器}为13
   -然后向下遍历发现没结点了,回到13的父节点10,更新temp为10
   -10没有其他子结点所以继续向上递归,并更新temp为6
   -访问6的另一个子结点11,不是我们要找的,继续向下;
   -11没有其他子结点,所以向上递归
   -回到3,更新temp为3;
   -回到1,更新temp为1;
   -去到4,找到第二个结点,输出temp中保存的值{1},并结束程序

Test2:寻找6和13的最近祖先

-使用DFS遍历来到6,发现第一个我们要寻找的结点,初始化temp为6;
-向下遍历来到10;
-向下遍历来到13,发现另一个要寻找的结点,输出temp中的值{6},结束程序

/******************************************/
代码实现起来并不复杂,算法复杂度O(n),其实大多数情况下我们都不需要遍历完所有节点就可以找到最近祖先了

不晓得这算法是不是我第一个发现的…如果那么好运,,,嘿嘿,我可得好好想个名字。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值