【问题标题】:To find loop in a singly linked list without using slow and fast pointer在不使用慢速和快速指针的情况下在单链表中查找循环
【发布时间】:2017-03-12 01:58:18
【问题描述】:

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

现在我的问题是
“是否有可能在不使用快速和慢速指针的情况下检测单链表中的循环?”强>

任何想法将不胜感激。
提前致谢。

【问题讨论】:

    标签: data-structures linked-list


    【解决方案1】:

    至少还有另外两种解决方案。

    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
    }
    

    一种破坏性的方法是在你去的时候反转链接。如果链表中有一个循环,那么当您的指针等于 null 时,它将位于根。那就是:

    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
    

    如果其中有一个循环,这确实有破坏列表的缺点。如果没有循环,您可以返回列表并反转链接。

    【讨论】:

      【解决方案2】:

      是的,当然。最直观的方法是遍历每个节点,检查你是否访问过这个节点。如果你之前访问过这个节点,这意味着有一个循环,这个特定的节点是循环的开始。

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

      时间复杂度 - O(n)

      空间复杂度 - O(n)

      boolean isCyclic(Node head){
        HashSet<Node> set = new HashSet<Node>();    
        while(head != NULL){
          if(set.contains(head))
             return true;
          set.add(head)
          head = head.next  
        }
        return false;
      }
      

      【讨论】:

      • 首先感谢。这是很好的方法。是否可以不使用额外的空间 O(n).?
      猜你喜欢
      • 1970-01-01
      • 2023-03-03
      • 2015-10-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多