2.5 Given a circular linked list, implement an algorithm which returns 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
GetLoopStart1()先找到相遇点,根据龟兔方法,该点一定是在环之内。然后从head开始,对每个节点都遍历一次环,当两个遍历指针相等时即为入口点。
GetLoopStart2()只需要O(N),根据答案写的。code很简单,但是算法确实想不到,算法证明:http://www.1point3acres.com/bbs/viewthread.php?tid=18162。
package Question2_5;
public class Question2_5
{
public static void main(String[] args)
{
Question2_5 q = new Question2_5();
q.AddToList(1);
q.AddToList(2);
q.AddToList(3);
q.AddToList(4);
q.AddToList(5);
q.AddToList(6);
q.AddToList(7);
q.AddToList(8);
Node temp = q.head.next;
for (int i = 0; i < 5; i++)
temp = temp.next;
q.GetTail().next = temp;
temp = q.GetLoopStart1();
temp.PrintNode();
temp = q.GetLoopStart2();
temp.PrintNode();
}
private Node head;
public Question2_5()
{
head = new Node(null, null);
}
public void AddToList(Integer e)
{
Node temp = head;
while (temp.next != null)
temp = temp.next;
temp.next = new Node(e, null);
}
public Node GetTail()
{
Node temp = head;
while (temp.next != null)
temp = temp.next;
return temp;
}
public Node GetLoopStart1()
{
Node temp1 = head.next;
Node temp2 = head.next;
// loop until temp1 and temp2 met each other
while (temp2 != null)
{
temp1 = temp1.next;
temp2 = temp2.next.next;
if (temp1 == temp2)
break;
}
// O(N^2) to find the start point
Node meetPointNode = temp1;
temp1 = head;
while (true)
{
temp1 = temp1.next;
temp2 = meetPointNode;
// For each node from the head, run the loop
do
{
if (temp1 == temp2)
return temp1;
temp2 = temp2.next;
} while (temp2 != meetPointNode);
}
}
public Node GetLoopStart2()
{
Node temp1 = head.next;
Node temp2 = head.next;
// loop until temp1 and temp2 met each other
while (temp2 != null)
{
temp1 = temp1.next;
temp2 = temp2.next.next;
if (temp1 == temp2)
break;
}
temp1 = head.next;
while (temp1 != temp2)
{
temp1 = temp1.next;
temp2 = temp2.next;
}
return temp1;
}
public void PrintList()
{
Node temp = head;
while (temp.next != null)
{
temp = temp.next;
System.out.println(temp.data + " ");
}
System.out.println();
}
private class Node
{
Node(Integer d, Node n)
{
data = d;
next = n;
}
void PrintNode()
{
System.out.println(data);
}
Integer data;
Node next;
}
}