在循环单链表中查找循环起点的解决方案
Solution to Finding Start of Loop in a Circular Singly Linked List
我发现这个问题的常见解决方案是使用 2 个指针,它们以不同的间隔在链表中前进(即让 p1 一次遍历一个节点,p2 一次遍历两个节点)直到 p1 和p2 相等。示例:Finding loop in a singly linked-list
但是为什么我们不能只使用一个Set来查看是否有重复的节点(前提是我们的节点没有默认的equals和hashCode被覆盖)。
应用下一个算法,将方法 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
}
我发现这个问题的常见解决方案是使用 2 个指针,它们以不同的间隔在链表中前进(即让 p1 一次遍历一个节点,p2 一次遍历两个节点)直到 p1 和p2 相等。示例:Finding loop in a singly linked-list
但是为什么我们不能只使用一个Set来查看是否有重复的节点(前提是我们的节点没有默认的equals和hashCode被覆盖)。
应用下一个算法,将方法 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
}