单链表相交问题(无环 &有环)

来源:互联网 发布:c 一维数组输入 编辑:程序博客网 时间:2024/06/01 07:33

在说明相交问题前需要先说明如何判断单向链表是否有环,并找出环入口。这是解决相交问题的基础点。本文参考了:http://blog.sina.com.cn/s/blog_6fb300a30100ng0s.html中讨论链表相交问题部分。这篇博文对面试中链表问题的总结挺全面,推荐大家阅读。

1.单向链表是否存在环

判断单链表是否存在环问题有固定的解法:用两个指针,一个指针一次走一步,一个指针一次走两步,如果该链表存在环,则两个指针一定会走到相同位置。如果不存在环,走得快的指针肯定先到达链表尾部。

2求环的开始点(入口)


存在一个规律:从链表头到环入口的距离 == 环入口到碰撞点的位置的距离。碰撞点是指:前面在判断链表是否有环时,两个指针最后相遇的位置。

设慢指针到碰撞点走的距离为s = x +y,快指针走的距离为2s. 2s - s = nr。 nr = x + y。 x = nr - y。这就表明一个指针p1从链表头走,一个从链表碰撞点p2走,那么当p1走了x,到达入口E,p2走了nr-y,即从原位置向后走了y步到达碰撞点,两者相遇。所以可以得到求解环入口算法crashNode(L),返回入口指针。若没有入口,返回NULL.

3.链表相交

image
第一种情况
image
  第二种情况
image
第三种情况

从上面的图可以看出:相交的情况存在三种情况:第一种是两个链表都没有环,第二种情况是两者都有环,且只有一个环入口。第三种情况是两者都有环,且环有两个入口。下面是不相交的情况:

第四种情况:
image
第五种情况
image
第六种情况

4伪代码实现

从上面的分析可以做如下判断相交算法描述:
CROSSLIST(L1,L2){    NODE  N1 = crashnode(L1);    NODE   N2 = crashnode(L2);    if(N1 == null  && N2 == null)// 表示两个链表没有环 第一种和第四种情况    {        step1:人为构环:将L1的尾指向L2的头。        node = crashnode(L1);        //若node == NULL,表示没有相交,若有入口,则是相交的第一个节点。    }    else  if((N1 == null && N2 != NULL)  || ( N1 != NULL && N2 == NULL))// 表示一个有环,一个无环,不可能相交; 第五种情况;           return NULL.    else if( N1 == N2  && N1 != NULL)// 表示两者都有环,且只有一个环入口 // 第二种情况           return N1;    else // 表示两者都有环    {       if在环内N1 能够到达N2 则表明两者共享一个环,有两个入口。return N1 or N2;//第三种情况;       else 两者无法到达,表明有两个环,且不相交。//第六种情况;    }}

5p.s.无环链表相交的另一种解法

image
前面判断这种情况下是否有环的做法是先构造环,再判断是否环构造成功。下面提供另一种思路:遍历两个链表,如果尾节点相同,就相交,遍历的同时,求出两个链表的长度LEN1,LEN2,然后从短链表的|LEN 2 - LEN1|节点开始一步遍历,长链表从头开始一步遍历,遍历到第一个相同的节点,就是第一个相交节点。

0 0
原创粉丝点击