Data structures 在单链表中查找循环而不使用慢速和快速指针

Data structures 在单链表中查找循环而不使用慢速和快速指针,data-structures,linked-list,Data Structures,Linked List,我们知道,为了检测链表中的循环,我们使用慢指针和快指针,首先用头节点初始化两个节点慢指针和快指针,然后向前两步遍历快指针,向前一步遍历慢指针。如果我们发现两个地址相等,那么,如果fast==null | | fast,则有循环。next==null则没有循环。现在我的问题是“是否有可能在单链接列表中检测循环而不使用快速和慢速指针?” 任何想法都将不胜感激。 提前谢谢。当然可以。最直观的方法是遍历每个节点并检查您是否访问过该节点。如果您之前访问过此节点,这意味着存在一个循环,并且此特定节点是循环的

我们知道,为了检测链表中的循环,我们使用慢指针和快指针,首先用头节点初始化两个节点慢指针和快指针,然后向前两步遍历快指针,向前一步遍历慢指针。
如果我们发现两个地址相等,那么,如果fast==null | | fast,则有循环。next==null则没有循环。

现在我的问题是
“是否有可能在单链接列表中检测循环而不使用快速和慢速指针?”

任何想法都将不胜感激。

提前谢谢。

当然可以。最直观的方法是遍历每个节点并检查您是否访问过该节点。如果您之前访问过此节点,这意味着存在一个循环,并且此特定节点是循环的开始

要检查您之前是否访问过该节点,您可以维护一个哈希集,该哈希集允许您检查是否存在时间复杂度为O(1)的元素。 检查下面的伪代码

时间复杂度-O(n)

空间复杂度-O(n)

boolean是循环的(节点头){
HashSet=newhashset();
while(head!=NULL){
if(集合包含(头部))
返回true;
集合。添加(头)
head=head.next
}
返回false;
}

当然可以。最直观的方法是遍历每个节点并检查您是否访问过该节点。如果您之前访问过此节点,这意味着存在一个循环,并且此特定节点是循环的开始

要检查您之前是否访问过该节点,您可以维护一个哈希集,该哈希集允许您检查是否存在时间复杂度为O(1)的元素。 检查下面的伪代码

时间复杂度-O(n)

空间复杂度-O(n)

boolean是循环的(节点头){
HashSet=newhashset();
while(head!=NULL){
if(集合包含(头部))
返回true;
集合。添加(头)
head=head.next
}
返回false;
}

至少还有两种解决方案

O(n^2)解决方案是跟踪节点编号。在每个节点上,返回头部并计算到达当前节点所需的
next
操作数。如果在执行n
next
操作之前到达第n个节点,则列表中有一个循环。即:

// assuming head is not null, and head doesn't point to itself
nodeNumber = 1
current = head.next
while (current != null)
{
    p = head
    counter = 0
    while (p != current && counter < nodeNumber)
    {
        p = p.next
        counter = counter + 1
    }
    if (p != current)
        there's a loop
    nodeNumber = nodeNumber + 1
}
if (head == null) || (head.next == null)
    no loop

prev = head
current = head.next
while (current != null)
{
    // save next position
    next = current.next
    // reverse the link
    current.next = prev
    // and move to the next node
    prev = current
    current = next
}
if (prev == head)
    there is a loop

这样做的缺点是,如果列表中有循环,则会将其销毁。如果没有循环,您可以返回列表并反转链接。

至少还有两种其他解决方案

O(n^2)解决方案是跟踪节点编号。在每个节点上,返回头部并计算到达当前节点所需的
next
操作数。如果在执行n
next
操作之前到达第n个节点,则列表中有一个循环。即:

// assuming head is not null, and head doesn't point to itself
nodeNumber = 1
current = head.next
while (current != null)
{
    p = head
    counter = 0
    while (p != current && counter < nodeNumber)
    {
        p = p.next
        counter = counter + 1
    }
    if (p != current)
        there's a loop
    nodeNumber = nodeNumber + 1
}
if (head == null) || (head.next == null)
    no loop

prev = head
current = head.next
while (current != null)
{
    // save next position
    next = current.next
    // reverse the link
    current.next = prev
    // and move to the next node
    prev = current
    current = next
}
if (prev == head)
    there is a loop

这样做的缺点是,如果列表中有循环,则会将其销毁。如果没有循环,您可以返回列表并反转链接。

首先,谢谢。这是一个很好的方法。不使用额外的空间O(n)是否可能?首先,谢谢。这是一个很好的方法。不使用额外的空间O(n)是否可能。?