【问题标题】:Solution to Finding Start of Loop in a Circular Singly Linked List在循环单链表中查找循环开始的解决方案
【发布时间】:2015-08-01 14:56:58
【问题描述】:
我发现这个问题的常见解决方案是使用 2 个指针以不同的时间间隔在链表中前进(即 p1 一次遍历一个节点,p2 一次遍历两个节点)直到 p1 和 p2 是等于。示例:Finding loop in a singly linked-list
但是为什么我们不能只使用一个 Set 来查看是否有重复节点(前提是我们的节点没有默认的 equals 和 hashCode 被覆盖)。
【问题讨论】:
标签:
set
hashset
singly-linked-list
【解决方案1】:
应用下一个算法,将方法 first 和 next 替换为您的语言中的正确方法
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
}