单链表寻找环的入口点

来源:互联网 发布:围棋编程点目方法 编辑:程序博客网 时间:2024/05/29 06:59
若存在环,如何找到环的入口点(即上图中的结点E)?
解答:
       如图中所示,设链起点到环入口点间的距离为x,环入口点到问题1中fast与low重合点的距离为y,又设在fast与low重合时fast已绕环n周(n>0),且此时low移动总长度为s,则fast移动总长度为2s,环的长度为r。则
s + nr = 2s,n>0      ①
s = x + y                  ②
由①式得
s = nr                 
代入②式得
nr = x + y
x = nr - y                  ③

        现让一指针p1从链表起点处开始遍历,指针p2从encounter处开始遍历,且p1和p2移动步长均为1。则当p1移动x步即到达环的入口点,由③式可知,此时p2也已移动x步即nr - y步。由于p2是从encounter处开始移动,故p2移动nr步是移回到了encounter处,再退y步则是到了环的入口点。也即,当p1移动x步第一次到达环的入口点时,p2也恰好到达了该入口点。

总之,设置两个指针,一个从起点开始,一个从相遇点开始,同时以step为1 向后遍历直到二者相遇时,此时相遇点位入口点

于是函数可写如下:

Node* findEntry(Node* head, Node* encounter){          Node *p1 = head, *p2 = encounter;        while(p1 != p2)        {               p1 = p1->next;              p2 = p2->next;         }        return p1;}