July大神微软等100题之第7题------判断两个链表相交(包含有无环),链表是否有环题目总结

今天才发现,当年考研的最后一题还有常数上更优的时间复杂度算法。。。


判断两个单链表是否相交:
我写的:
遍历Link1,O(L1)
遍历Link2,O(L2)
将长的链表指针后移|L2-L1|个长度,然后两个指针逐个后移,每次判断是否两个指针值相同


时间复杂度O(L1+L2+max(L1,L2))

PS:记得后来在admis实验室我的位子上,还和if和炮哥两位大神讨论过这个题目- -



编程之美上:
判断两个链表最后一个结点是否相同,
时间复杂度O(L1+L2)




检测两个链表是否相交,(返回第一个公共结点,),检测一个链表是否有环(包括循环链表和尾环链表)问题的总结。


问题1:检测一个单链表是否有环:


方法1: hash表
遍历的同时,对结点的地址值建立一个hash table(具体为插入操作,处理collision):每次访问一个结点,查找hash表,如果找不到,插入,否则返回结果,有环。遍历直到访问结束。
之前还考虑过同一个value和同义词怎么区分,对hash概念模糊,看了某大神的hash查找代码后顿时豁然开朗,完全不用考虑这个问题。通过一个while循环返回的指针是否为空来区分。


方法2:bool数组
初始化一个较大bool数组,赋值为false, 每次访问一个结点,如果对应bool数组值为false,改为true,否则,返回结果有环。遍历直到访问结束。


方法3:倒置链表(该方法仅能检测循环链表)
倒置链表,pprev,p,pnext,每次判断pnext是否为head 如果出现,返回结果,有环。
由于破坏了链表结构,需要再倒置一次


方法4:快慢指针(面试官需要的算法)
设置fast slow指针,fast走两步,slow走一步。分析后面再看




问题1补充:如果还需返回第一个环的入口结点?
从相遇结点,和head两个位置同时向后遍历,第一次相遇的点即为环入口结点。


关于这个的理论基础简要说明如下:

notations:

m: 两个指针移动得次数

Nnonloop:非环部分的长度(结点个数)

Nloop:环部分的长度(结点个数)

Iloopmeetindex: fast slow指针环内相遇的位置,用环内从环头为1开始的index

r1,r2,r3均为不小于0的整数



2m=Nnonloop-1+r1*Nloop+Iloopmeetindex -----(1)
m=Nnonloop-1+r2*Nloop+Iloopmeetindex -------(2)


(1)-(2): m=(r1-r2)Nloop -----(3)  其中,r1-r2>=1, m>=1


由(2) (3):
    (r1-2r2)Nloop=Nnonloop-1+Iloopmeetindex ------(4)

我们要证明:
   Nnonloop=r3*Nloop+ (Nnonloop+Nloop-(Iloopmeetindex+Nnonloop-1))
                     =r3*Nloop+ (Nloop-Iloopmeetindex+1)    -----------(5)

从(4)移项发现:
Nnonloop=(r1-2*r2)+1-Iloopmeetindex ------(6)
其中r1-2*r2>=1,即能找到一个r3使得r3+1>=1,因此得证。






问题2:检测两个单链表是否相交(12年CS考研最后一题,微软面试题):


方法1:分别遍历两个链表,长度分别为L1,L2,然后较长链表指针后移|L1-L2|长度,然后两个指针同时后移,每次判断是否相同
当年考研我写的答案,这个方法还可以返回首个公共结点,如果不用的话,时间复杂度比编程之美的长一些


方法2:分别遍历两个链表,长度分别为L1,L2,记录两个尾结点(编程之美的答案,还未验证)。缺陷是不能返回首个公共结点。


方法3:还是hash表
对一个遍历,同时建立hash表,然后对另一个遍历,同时查hash表


方法4:将两个link首尾相连
如果相交,必出现环,再用检测环来检测


问题2补充:如果两个链表可能是有环的链表,怎么判?


分析:只可能出现两个都是环的情况,不可能是一个无环,一个有环。
并且情况可以分为两种,一种是公共结点在环外面,一种是在环内。
都已经思考到这一步了,结果都没想到好的解决方案,最后还是想到一个笨得hash方法。后来看了July大神给的答案,又一次豁然开朗= =
先检测其中一个是否有环,如果有的话,判断环内相遇的结点(fast slow指针法)是否在另一个链表出现,因为如果两个链表中有环,相交的的话一定公用环的所有结点,只需检测一个中环内结点是否在另一个链表即可得出结论。
觉得自己有时候思考问题到一定程度了,连简单的都想不到= =



这篇帖子真的脱了好久,主要是关于那段理论的证明,以及最后有环判交方法的思考= =







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值