转 java

转自 https://blog.csdn.net/u010983881/article/details/78896293 

1.穷举遍历

首先从头节点开始,依次遍历单链表的每一个节点。每遍历到一个新节点,就从头节点重新遍历新节点之前的所有节点,用新节点ID和此节点之前所有节点ID依次作比较。如果发现新节点之前的所有节点当中存在相同节点ID,则说明该节点被遍历过两次,链表有环;如果之前的所有节点当中不存在相同的节点,就继续遍历下一个新节点,继续重复刚才的操作。那么算法的时间复杂度可以简单地理解成 O(N*N)。而此算法没有创建额外存储空间,空间复杂度可以简单地理解成为O(1)。

2.快慢指针

首先创建两个指针1和2(在java里就是两个对象引用),同时指向这个链表的头节点。然后开始一个大循环,在循环体中,让指针1每次向下移动一个节点,让指针2每次向下移动两个节点,然后比较两个指针指向的节点是否相同。如果相同,则判断出链表有环,如果不同,则继续下一次循环。

此方法也可以用一个更生动的例子来形容:在一个环形跑道上,两个运动员在同一地点起跑,一个运动员速度快,一个运动员速度慢。当两人跑了一段时间,速度快的运动员必然会从速度慢的运动员身后再次追上并超过,原因很简单,因为跑道是环形的。

/**
 * 判断单链表是否存在环
 * @param head
 * @return
 */
public static <T> boolean isLoopList(ListNode<T> head){
    ListNode<T> slowPointer, fastPointer;

    //使用快慢指针,慢指针每次向前一步,快指针每次两步
    slowPointer = fastPointer = head;
    while(fastPointer != null && fastPointer.next != null){
        slowPointer = slowPointer.next;
        fastPointer = fastPointer.next.next;

        //两指针相遇则有环
        if(slowPointer == fastPointer){
            return true;
        }
    }
    return false;
}

原文地址:https://www.cnblogs.com/20158424-hxlz/p/10316800.html