两个单链表相交的系列问题

题目要求:
给定两个单链表,有可能有环,也有可能无环,现在请判断两个单链表是否相交,并给出相交的起始位置。

题目分析:
如果遇到有点良心的面试官,他会一步步问你,首先问你怎么判断一个链表是否有环,然后再问你无环的情况下,怎么判断两个链表是否相交,有环的情况下怎么判断两个链表是否相交?
首先,几个概念需要解释一下,单链表的相交,并不是两个链表内的值相等就叫相交,而是两个链表实实在在相交了,也就是说,在某个点相交后,两个链表后面部分就变成一条链子了,并且,相交后的链表就不可能再分开了,因为,单链表只有一个next指针,如果再分叉,就有两个next指针了,就不符合单链表特性了。
好的,那么单链表相交的一系列问题,其实就是细分为三个问题,遇到狗逼的面试官,上来直接问怎么判断先相交的,其实就是在问以下三个问题:
1.怎么判断单链表是否有环?
2.怎么判断两个无环的单链表是否相交?
3.怎么判断两个有环的单链表是否相交?

思路分析:
怎么判断单链表是否有环?
判断单链表是否有环,其实就是判断,在遍历的过程中,是否出现重复节点,注意,是重复节点,而不是重复value。 想到重复节点,第一反应,散列表结构,因为只需要保存key,因此,用hashSet,每遍历一个节点,就放入set中,注意,放的是节点,而不是value,如果hascontains方法返回true,说明有环。
第二种方法,如果题目要求空间复杂度O(1),链表结构,经常要求空间复杂度O(1),那么,可以用快慢指针解决。两个指针,一个慢指针,一个快指针,如有环,那么快慢指针一定会相遇,并且,相遇时,将快指针放到头节点处,继续跑,此时快慢指针每次都只走一步,当再相遇时,那个地方就是环路的起点,也就是入环节点 这是经过证明的一个结论,感觉很神奇对吧?用数学归纳法可以证明,证明没必要,记住这个结论就好了,环路问题可以用快慢指针解决。

怎么判断两个无环的单链表是否相交?
首先,需要知道一点是,如果一个单链表有环,另一个无环,那么他们不可能相交。
简单办法,还是利用散列表,遍历一个链表,将其中所有节点放入set中,然后,再遍历另一个,如果节点在set中出现过,则说明相交。
第二种方法,如果题目要求空间复杂度O(1),怎么实现?
首先,将每个链表遍历一遍,记录下来链表的总长度和最后一个节点。然后判断,如果两个链表的最后一个节点是不是同一个节点,就是判断内存地址是否相同,如果不是同一个内存地址,则两个链表肯定不相交。如果两个链表相交的话,则他们的最后一个节点一定是同一个节点。因为,如果两个链表在某处相交,则他们后面的所有节点全部都相同,不可能出现分叉的情况,因为分叉就代表不止一个next,就不符合单链表的定义了。因此,判断完是否出现相交后,然后看两个单链表的长度,用长度较长的减去长度短的,比如,一个链表长度是100,另一个是80,则让100的先跑20步,然后两个单链表一起跑,依次比较每一个节点,当出现相同时,就是相交的起点位置。

怎么判断两个有环的单链表是否相交?
两个有环链表,三种情况:
1.两个链表先相交,再出现环。
2.两个有环链表根本就没相交。
3.两个有环链表在环上相交。
首先,判断出两个链表都出现环的时候,需要保存下两个链表的入环节点,也就是环上的第一个节点。
首先,如果两个链表的入环节点相同,则是第一种情况。在这种情况下,如果求第一个相交的节点,其实就等同于无环链表相交的情况。
如果两个链表的入环节点不相同,则是23的情况。
此时,让第一个链表,在其入环节点处,继续往下走,如果碰到了第二个链表的入环节点,则说明是第三种情况,如果循环了一圈又回来了,则说明根本就没相交,也就是第二种情况。

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页