编程之美-3.6-编程判断两个链表是否相交

1. 简述

    给出两个链表的头指针,比如h1,h2,判断这两个链表是否相交。这里是为了简化问题,我们假设两个链表不带环。
    扩展:如果链表可能有环呢?
    扩展:如何求出两个相交链表的相交的第一个节点。

2. 分析

    这道题,个人感觉理解的还是相对比较清楚完整。主要就是两个问题,问题一,两个链表是否相交,问题二,两个链表如果相交,求得相交第一个节点。
    如果两个链表相交,那么要么两个链表都没有环,要么都有环。所以我们首先判断h1和h2是否有环:三种情况:一个有环一个没环(这种情况说明肯定不相交),两个都有环(需要进一步判断),两个都没有环(需要进一步判断)。
    一个链表是否有环的判断方法很简单,就是两个指针,一个一次走一步,另一个一次走两步,如果有环,那么两个指针早晚进入环,两个指针的相对速度正好是1,因此距离会一点一点减少,直到两个指针相遇,如果其中一个指针变为空了,说明不存在环。
    对于都没有环的两个链表:如果相交比如是从尾部向头部的若干个节点相交(至少1个),可以直接判断两个链表的最后一个节点地址是否相同。如果要寻找第一个相交的节点,也很容易,计算两个节点的长度差,假设为k,让较长的链表先走k步,然后,每走一步前先判断节点地址是否相等即可。
    对于都有环的两个链表:如果他们相交那么两个链表的环的部分必然是重合的,因为一个链表如果有环必然是形如数字6的情况。注意这里不能用两个指针分别从两个链表走,因为,如果链表相交,那么一快一慢的指针会相交,但是如果链表不相交,那么两个指针永远都不会相交,而且都在各自的环中不停的走,这样无法结束循环的。这里需要转换思路,首先求得链表进入环的第一个节点,因为这个节点也在环上,所以这个节点必然是相交的,只要判断这个节点地址是否相同即可。对于相交的第一个节点,其实如果找到两个链表进入环的第一个节点了,那么从头节点到这个节点,就转化为两个单链表的形式了,进入环的第一个节点相当于单链表的最后一个节点。
    关键在于寻找带环链表的进入环的那个节点。方法如下:两个指针,一个走一步,一个走两步,在环中相遇位置为X,然后从头节点和X位置,分别一步一步的走,每次判断是否相遇,相遇点就是所求节点。
    证明如下:假设头节点位置为A,第一个节点为M,相遇节点为X,环长为Len。
    因为快节点每次比慢节点快一步,慢节点进入后快节点不用一圈就能赶上慢节点了。
    慢节点走的路程 = AM + MX
    快节点走的路程 = AM + MX  + n * Len
    2*(AM + MX ) = AM + MX + n *Len
    AM + MX = n*Len
    AM = (n-1)*Len + XM 就是这句话了,说明从A到M的距离与X到M的距离,同余环长。因此分别从A和X走,必然相交于X节点。

3. 参考

    编程之美,3.6节,编程判断两个链表是否相交

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值