- 论坛徽章:
- 0
|
想了一下,似乎下面的算法可以:O(1)空间,O(n)时间。
两个额外指针p1, p2,开始都指向头S。设需要找到的循环部分第一个结点的位置为A,S到A的距离为x (x可能为0),链表的循环部分长度为y (y > 0)。
算法开始和判断循环的方法一样:令p1每次走一步,p2每次走两步,我们知道,如果链表有环,最后p1和p2一定在环上某个地方B相遇,我们设A-B之间的距离为z (z可能为0)。
很显然,p1走了x+z步,那么p2走了2(x+z)步,由于p1和p2在这么多步后相遇,因此有2(x+z) - (x+z) = K*y (K > 0的整数),因此我们有x+z = K*y。
假如我们能让p1在B点开始继续往前走x步的话,它一定会走到A,因为z+x是y的倍数。有人会说,费话如果知道x的话,我只要让p2从起点S开始往前走x步,不就也能走到A吗?其实解法就是这么简单,让p1在刚刚相遇的地方B继续一次走一步,而p2从起点S开始一次走一步,那么它们第一次相遇的地方一定是A,并且正好经过了x步(当然你不需要计数)。
这就是算法。还是比如下面的例子:0->1->2->3->4->5->6->7->8->(3)
刚开始p1, p2都在0,p1一次走一步,p2一次走两步,它们最终会在结点6相遇。这时候让p1继续从6开始往前走,而p2从0开始也一次往前走1步,那么我么就会发现它们会相遇在3,返回这个地址就是所需要的解。 |
评分
-
查看全部评分
|