http://blog.163.com/song_0803/blog/static/4609759720120910373784/
这里是网上找到的一个分析的比较全面的文章。
想到这个问题是因为一场笔试,题目类似,笔试完,感觉做的不够理想。
一.无环的两个链表相交:(大家就不要想尾部是否分叉了,这个肯定是单链表,只有一个next指针,所以不会分叉)

按照原博主的想法:
1.直接法:就是把每个M和每个N链表比较,这样的复杂度O(M*N)
2.hash表:把M链表中每个元素的地址散列到hash表中,在寻找N中地址hash是否有一样的,我们都知道,hash表的查找效率是O(1),这样整体的时间复杂度就是O(M+N)//(Hash函数可以优化:由于节点地址指针就是一个整型,假设链表都是在堆中动态创建的,可以使用堆的起始地址作为偏移量,以地址减去这个偏移量作为Hash函数)
3.先跳过原博主的第三个方法,因为我认为这个是最好的,比Hash表还要好,因为Hash表多占了内存。
第四个方法:两个链表有长有短,先知道他们的长度,让长的链表,先跳MAX(M,N)-MIN(M,N)个距离,这样后面它们的”起点“就是一样的了,然后他们同时前进,并比较,若相同,肯定是相交的那个点。
4.原博主的第三个方法:
也说明一下,三四方法原理其实是一样的,就是:两个链表相交的话,肯定最后一个点是一样的,那从后数,相交点肯定距离最后点也是一样的,这就是上个方法的思路。但是你不觉得奇怪?为什么不直接比较最后一个点呢?对,直接比较最后一个点,这就是这第四个方法的思路。
现在来分析下:
4方法只需要M+N的移动,比较一次就可以了,不要知道MN的大小。
3方法需要计算MN的大小(这里我们可以认为,这个是事先知道的,不用求的,因为一般增删改后都是会更新结构离的lengh的),我们可能只需要M(不同部分长度)+N(不同部分长度)的移动,但是需要MAX(M(不同部分长度,N(不同部分长度))次比较,我们知道”比较“是比”赋值“耗时的【
比较耗时长
比较有一个读a和b值得过程,然后比较要建立一个新的区间存储比较结果,
而复制只是读取b的值,然后存储到a的位置,根本不需要读取a原来的值。
】所以4方法就比3方法好多了,当然如果相交点很近的话也不一定,但是谁又知道相交点在哪呢,所以还是,4的时间复杂度平均更低。
2方法是以前认为最好的,但是却不是这个问题的最优解,不仅要hash(M+N)次,还要比较M+N,显然不是最好的,还要占空间。
二.两个有环
首先,我不认可博主的方法:
1.链表中是否有环的判断:我觉得应该用:Hash来判断。
楼主的方法是个用数学来解决的,我觉得太浪费时间了,而且让方程来解的方法一般都不是方法(只是感觉),楼主能想到这个方法来解决也是让我很佩服,但觉得太繁琐了。
2.链表有环,判断环的入口点:
用哈希相遇的那个点就是入口点。
3.相交的判断:(相交肯定是共享结尾环的,当然可能入口不同)
浙公网安备 33010602011771号