链表中换的入口节点
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def EntryNodeOfLoop(self, pHead):
# write code here
# 推荐解法,双指针方法(新学习到的思路)两个指针,初始时都在链表开头,然后快指针每次移两格
# 慢指针每次移一格,如果有环,那么快慢指针一定会在环中某位置相遇,且快指针至少超慢指针一圈
# 设相遇时快指针走过s,慢指针走过f,那么s=2f
# 因为快指针至少超慢指针一圈,设环周长为c,那么s=f+?c
# 解得f=?c,再设链表除了环以外的长度为a,那么慢指针要走到环入口处需要在现在基础上再加a
# 因此在此时将快指针重新置为链表开头,并且与慢指针一起每次走一格,因为这样可以保证快慢指针
# 同时走了a步,并且在环入口相遇
if not pHead:
return None
k, m = pHead, pHead
while k and k.next:
k = k.next.next
m = m.next
if k == m:
break
if not k or not k.next:
return None
k = pHead
while k != m:
k = k.next
m = m.next
return m
# 思想简单的解法,但时间空间复杂度高
# 建立空集合,遍历链表,每走一步都保存现在的节点在集合中,直到找到重复的节点
head_set = {}
while pHead:
if pHead not in head_set.keys():
head_set[pHead] = 1
pHead = pHead.next
else:
return pHead