Linked List Cycle I

Given a linked list, determine if it has a cycle in it.

Follow up: Can you solve it without using extra space?

快慢指针法

复杂度

时间 O(N) 空间 O(1)

思路

这是一道非常经典的双指针题。我们从头设置一个快指针,一个慢指针。快指针一次走两步,慢指针一次走一步,如果快指针走到了尽头,则说明链表无环。如果快指针和慢指针相遇,则说明链表有环。为什么相遇就说明有环呢?设想一个有环链表,快慢指针最后都会走到环上,而这个环就像一个环形跑道一样,慢指针在后面,快指针在前面,但实际上快指针也在追慢指针,希望能超慢指针一圈。他们在这个跑道上,总会有一天快指针追上了慢指针。我们不用担心快指针跳过了慢指针,因为他们两的速度差是1,所以她们俩在环上的距离总是每次减1,最后总能减到0。

代码

public class Solution {
    public boolean hasCycle(ListNode head) {
        ListNode slow = head;
        ListNode fast = head;
        while(fast != null && fast.next != null){
            slow = slow.next;
            fast = fast.next.next;
            if(fast == slow){
                return true;
            }
        }
        return false;
    }
}

2018/10

func hasCycle(head *ListNode) bool {
    fast := head
    slow := head
    // if fast.Next == nil and fast != slow, there can't be a cycle
    for fast != nil && fast.Next != nil {
        fast = fast.Next.Next
        slow = slow.Next
        if fast == slow {
            return true
        }
    }
    return false
}

Linked List Cycle II

Given a linked list, return the node where the cycle begins. If there is no cycle, return null.

Note: Do not modify the linked list.

Follow up: Can you solve it without using extra space?

快慢指针法

复杂度

时间 O(N) 空间 O(1)

思路

这题是基于上一题,上一题我们发现相遇后就返回true了,而这里我们还要继续找到环的起始点。假设快慢指针在环上第k个节点相遇,而环的起点是链表第m个节点,环的总长度是n。此时慢指针再走n-k步就回到了环的开头,而此时快指针已经走了m+k步。如果我们这时候将快指针放回起点,并让它也一次走1步,这样当两个节点再次相遇时,相遇点就是环的起点。

代码

public class Solution {
    public ListNode detectCycle(ListNode head) {
        ListNode slow = head;
        ListNode fast = head;
        while(fast != null && fast.next != null){
            fast = fast.next.next;
            slow = slow.next;
            if(fast == slow){
                // 找相遇点
                slow = head;
                while(slow != fast){
                    slow = slow.next;
                    fast = fast.next;
                }
                return slow;
            }
        }
        return null;
    }
}

ethannnli
858 声望360 粉丝