我发现这个问题的常见解决方案是使用以不同间隔通过链表前进的2个指针(即,p1一次遍历一个节点,p2一次遍历两个节点),直到p1和p2为等于。示例:Finding loop in a singly linked-list
但是为什么我们不能只使用Set来查看是否存在重复的节点(前提是我们的节点没有默认的equals和hashCode被覆盖)。
答案 0 :(得分:0)
应用下一个算法,将第一个和第二个方法替换为正确的方法,如您的语言
slow=llist.first
fast=slow.next
while(true)
{
if (slow==null || fast == null)
return false// not circular
if (fast==slow)
return true//it is cirular
fast=fast.next;if (fast!=null)fast=fast.next;
slow=slow.next;
}
这是C#中的一个详细示例:
public class Node<T>
{
public Node<T> Next { get; set; }
public T Value { get; set; }
}
class LinkedList<T>
{
public Node<T> First { get; set; }
public Node<T> Last { get; set; }
public void Add(T value)
{
Add(new Node<T> { Value = value });
}
public void Add(Node<T> node)
{
if (First == null)
{
First = node;
Last = node;
}
else
{
Last.Next = node;
Last = node;
}
}
}
static int IndexOfCiruclarity<T>(LinkedList<T> llist)
{
var slow = llist.First;
var fast = slow.Next;
int index = -1;
while (true)
{
index++;
if (slow == null || fast == null)
return -1;
if (fast == slow)
return index;
fast = fast.Next;
if (fast != null) fast = fast.Next;
else
return -1;
slow = slow.Next;
}
}
void TestCircularity()
{
LinkedList<int> r = new LinkedList<int>();
for (int i = 0; i < 10; i++)
r.Add(i);
r.Add(r.First);
var ci = IndexOfCiruclarity(r);
//ci = 9
}