Topic: Given a circular linked list, implement an algorithm which returns the node at the beginning of the loop.
DEFINITION Circular linked list: A(corrupt) linked list in which a node’s next pointer points to an earlier node, so as to make a loop in the linked list.
EXAMPLE Input: A->B->C->D->E->C (the same C as earlier); Output:C.
// 方法:1)Detect if Linked List has a loop:use FastRunner(two steps at a time)/Slow Runner (one step)approach. If there is a loop, they must meet.
2)When do they collide. Assume “non-looped” part is a, the size of loop is b, after k steps, two pointers meet, there is k-a+nb=2k-aà k=nb. The meet point is nb-a from the start loop, that means: a=meet_pint to loop_start. 简单来说,就是快慢指针的相遇点,两同步指针,一个从相遇点,一个从起点走,相遇的地方就是loop的起点。
public class List {
int data;
List next;
public List(int d) {
this.data = d;
this.next = null;
}
public List(){};
void appendToTail(int d) {//依次在最后一个节点的后面追加元素
List end = new List(d);
List n = this;
while (n.next != null) {//判断是否是最后一个节点,如果不是,往后移
n = n.next;
}
n.next = end;//把这个节点设为最后一个节点
}
void print() {
List n = this;
System.out.print("{");
while (n != null) {
if (n.next != null)
System.out.print(n.data + ", ");
else
System.out.println(n.data + "}");
n = n.next;
}
}
public static List Find_Loop_Start(List head){
List fast=head;
List slow1=head;
// find the meeting point
while(fast!=null &&fast.next!=null){
slow1=slow1.next;
fast=fast.next.next;//注意设置2步长的方法
if(slow1==fast){
break;
}
}
// if no loop, return null,补救上一个循环
if(fast==null||fast.next==null){
return null;
}
List slow2=head;
while(slow1!=slow2){
slow1=slow1.next;
slow2=slow2.next;
}
return slow2;
}
public static void main(String args[]) {
List A = new List(0);
A.appendToTail(1);
A.appendToTail(2);
A.appendToTail(3);
A.appendToTail(4);
A.next.next.next.next.next=A.next.next;
System.out.println(Find_Loop_Start(A).data);//这里一定要加println,不然是不会打印的
}
}
//结果
2