题目:
给定一个链表的头节点 head
,返回链表开始入环的第一个节点。 如果链表无环,则返回 null
。
如果链表中有某个节点,可以通过连续跟踪 next
指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos
来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos
是 -1
,则在该链表中没有环。注意:pos
不作为参数进行传递,仅仅是为了标识链表的实际情况。
不允许修改 链表。
示例 1:
输入:head = [3,2,0,-4], pos = 1 输出:返回索引为 1 的链表节点 解释:链表中有一个环,其尾部连接到第二个节点。
示例 2:
输入:head = [1,2], pos = 0 输出:返回索引为 0 的链表节点 解释:链表中有一个环,其尾部连接到第一个节点。
示例 3:
输入:head = [1], pos = -1 输出:返回 null 解释:链表中没有环。
提示:
- 链表中节点的数目范围在范围
[0, 104]
内 -105 <= Node.val <= 105
pos
的值为-1
或者链表中的一个有效索引
进阶:你是否可以使用 O(1)
空间解决此题?
解题思路:
方法一:
使用哈希表进行存储遍历过的指针地址,如果该地址被遍历过说明是环形链表的起始位置
代码:
class Solution:
def detectCycle(self, head):
situation = set()
p = head
flag = 0
while p:
if p in situation:
return p
situation.add(p)
p = p.next
return None
方法二:
使用快慢指针的想法,假设slow和fast指针在M点交汇,此时fast指针走过的路程应该是a+n(b+c),注意并不知道环路有多少节点,所以应该假设走了n次环路,此时slow应该走过的路程是a+b,根据快慢指针的定义可以知道,2(a+b) = a+n(b+c),a = (n-1) (b+c)+c,此时想要判断环路的起始节点,只要让一个新的节点从head出发,走过路程a个节点,slow节点也会从M走到环路的起始节点。
代码:
class Solution:
def detectCycle(self, head):
if not head or not head.next:
return None
p = head
q = head
while q!=None:
if not q or not q.next:
return None
p = p.next
q = q.next.next
if q==p:
str_p = head
while str_p!=p:
str_p = str_p.next
p = p.next
return str_p