链表相交问题

单链表可能有环,也可能无环。给定两个单链表的头节点head1和head2,这两个链表可能相交,也可能不相交。请实现一个函数,如果两个链表相交,请返回相交的第一个节点;如果不相交,返回null即可。

要求:如果链表1的长度为N,链表2的长度为M,时间复杂度请达到O(N+M),额外空间复杂度请达到O(1)。

第一步:先确定是否有环
第一种方法:将见到的节点加入到哈希set,如果发现已经存在,那么就是有环的。加入哈希表的是每个元素的内存地址。

第二种方法:如果想不使用哈希表来实现找环入口节点的话,那么我们可以准备两个指针,一个是快指针,一个是慢指针,快指针一次走两步,慢指针一次走一步,如果没有环,那么快指针最终得到空,如果有环,快指针与慢指针一定在环上某个节点处相遇(地址一致),此时将快指针放到开始处,并且步长改为一步,然后同时移动快指针与慢指针,两者必在环入口处相遇。时间复杂度为O(N),两圈内必相遇。

第二步:我们找出head1链表的入口节点loop1,我们找到head2的入口节点loop2。
情况1:若loop1 == null && loop2 == null
对于两个无环链表的相交问题,形状为平行线或者Y。我们可以使用哈希表来完成判断交点,先将一条链表中的所有元素加入到hashset中,再遍历另一条链表 ,如果遇到一个节点在hashset中存在,那么就意味着该节点为交点。如果不用哈希表,先遍历其中一个链表,找到其中的结尾以及统计长度。遍历另一个链表,找到其中的结尾以及统计长度。如果他们俩的最后一个节点不相同,那么一定不相交,如果相等,那么我们可以通过以下方式来确定入环节点:已知两个链表的长度,先让较长链表向下移动长-短个节点,然后让两条链表一起移动,那么他们必定同时相交,即第一个相同的元素必为入口。

情况2:若loop1 != null && loop2 == null || loop1 == null && loop2 != null
结论:必然不会相交,脑补的所有结构都会破坏单链表只有next指针这个结构。

情况3:若loop1 != null && loop2 != null 则会有以下三种情况。

 

 

怎么区分以上三种情况,可以由我们在判断是否有环的函数中得到的入口节点,如果两个入口节点是同一个节点,那么就是第二种结构,然后可以反推到两个链表的第一个交点。(此处可以复用,两个无环单链表的第一个交点的求法)
如果两个有环链表的入口不一样呢?那就是1或者3,怎么区分这两种情况呢,我让第一个入环节点继续往下走,一定可以回到自己,如果都回到自己了,还没有遇到过另一个链表的入环节点,那么就是第一种结构,否则是第三种结构。第三种情况中返回第一个链表的入环节点或者是第二个链表的入环节点都对。

posted @ 2021-12-28 17:15  keep每天进步一点点  阅读(75)  评论(0)    收藏  举报