如何判断两个链表相交及找到第一个相交点

转载自:http://www.cnblogs.com/BeyondAnyTime/archive/2012/07/06/2580026.html

下面附上本文及一些个人见解:

我们学一个算法,一定是为了用吧,所谓“学以致用”吗?那么判断两个链表是否相交有什么用呢?这是因为一旦两个链表出现相交的情况,就可能发生这样的情况,程序释放了链表La的所有节点,这样就导致了另外一个与之有相交节点的链表Lb中的节点也释放了,而Lb的使用者,可能并不知道事实的真相,这会带来很大的麻烦。

1.问题分析

  看看两个链表相交到底是怎么回事吧,有这样的的几个事实:(假设链表中不存在环)

  (1)一旦两个链表相交,那么两个链表中的节点一定有相同地址。

  (2)一旦两个链表相交,那么两个链表从相交节点开始到尾节点一定都是相同的节点。

  分析出来了问题的本质,那么思路也就自然有了。

2.问题解法

2.1 哈希解法:

  既然连个链表一旦相交,相交节点一定有相同的内存地址,而不同的节点内存地址一定是不同的,那么不妨利用内存地址建立哈希表,如此通过判断两个链表中是否存在内存地址相同的节点判断两个链表是否相交。具体做法是:遍历第一个链表,并利用地址建立哈希表,遍历第二个链表,看看地址哈希值是否和第一个表中的节点地址值有相同即可判断两个链表是否相交。

  时间复杂度O(length1 + length2)

  空间复杂度O(length1)

  分析:时间复杂度是线性的,可以接受,并且可以顺便找到第一个相交节点,但是却增加了O(length1)的空间复杂度,这显然不能令人满意。

2.2 问题转化

  如果两个链表中存在相交节点,那么将第二个链表接到第一个链表的后面,然后从第二个链表的表头开始遍历,如果存在环,则遍历过程一定会回到链表二的表头节点。可是这种方法似乎并不能找到第一个相交节点。怎么办呢?怎样才能判断链表中是否存在环,并且找到环的开始节点呢?

        /*注:如果两个链表中存在相交节点,则在将第二个链表接到第一个链表的后面后,新构成的链表为有环单链表,问题转化为判断新的单链表是否有环以及连接点(可参考前面blog)*/

2.3 抓住要点

  不妨遍历每个链表保存最后一个节点,看看最后一个节点是否是同一个节点,这种情况时间复杂度是O(length1 + length2)。基本也不需要什么空间,似乎是一个不错的想法哦,那么怎么找到第一个相交节点呢?可以遍历的过程中记录链表的长度L1和L2(假设L1>L2)这是遍历找到第一个链表中的第L1 - L2节点,然后链表一从第L1-L2个节点开始遍历,链表二从第一个节点遍历,每次前进一步,直到找到第一个相同的节点,则可以认为两个链表存在相交节点,并且该点即为第一个相交节点。这种解法的时间复杂度也是线性的,但是如果两个链表长度相差不多时,时间复杂度还是不错的。

  到这里,我知道的几种典型的解法就说完了。欢迎大神们提供新的思路!!

3.问题扩展:(思考)

  baidu曾经出过这样的一个笔试题目,归根到底也是找到两个链表是否存在相同的节点,但是数据量很大,即链表长度是上亿的。想想那么应该怎么处理呢?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值