链接:
题目:
Given a linked list, determine if it has a cycle in it.Notes:
Can you solve it without using extra space?解析:
这个问题需要注意几种情况:1. 空链表不成环
2. 一个节点自环
3. 一条链表完整成环
不能开额外的空间,即空间复杂度是o(1)。该问题是经典面试问题,其标准解法是用两个指针,一快一慢,如果fast指针在遍历过程中,遍历到了NULL节点说明链表没有环。如果fast指针能够追上慢的指针,则有环。
解答:
# Definition for singly-linked list. # class ListNode(object): # def __init__(self, x): # self.val = x # self.next = None class Solution(object): def hasCycle(self, head): """ :type head: ListNode :rtype: bool """ if not head: return False fast = slow = head while fast and fast.next: fast = fast.next.next slow = slow.next if fast == slow: return True return False
进阶:
判断环入口位置
我们假定链表头到环入口的距离是len,环入口到slow和fast交汇点的距离为x,环的长度为R。slow和fast第一次交汇时,设slow走的长度为:d = len + x,而fast走的长度为:2d = len + nR + x,(n >= 1),从而我们可以得知:2len + 2x = len + nR + x,即len = nR - x,(n >= 1),于是我们可以得到这样的算法。关于环入口算法的详细讲解,可以参考码龙喵
# Definition for singly-linked list. # class ListNode(object): # def __init__(self, x): # self.val = x # self.next = None class Solution(object): def hasCycle(self, head): """ :type head: ListNode :rtype: bool """ if not head: return False fast = slow = head while fast and fast.next: fast = fast.next.next slow = slow.next if fast == slow: return break if fast or fast.next: return False cur = head inter = slow while cur != inter: cur = cur.next inter = inter.next return cur