当前位置

网站首页> 程序设计 > 开源项目 > 程序开发 > 浏览文章

[Leecode] Linked List Cycle 链表环

作者:小梦 来源: 网络 时间: 2024-01-14 阅读:

Linked List Cycle I

快慢指针法

复杂度

时间 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;    }}

Linked List Cycle II

快慢指针法

复杂度

时间 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;    }}

相关阅读

热点阅读

网友最爱