哈希法
c++中有unordered_set,python中有set,作为哈希的集合,遍历链表时,若当前指针在集合中就说明有环,返回当前指针,否则将指针加入集合,最后若是正常退出循环表示没有环,返回NULL。
//c++
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
unordered_set<ListNode*> a;
while(head)
{
if(a.count(head)) return head;
a.insert(head);
head=head->next;
}
return NULL;
}
};
#python
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]:
a=set()
while(head):
if head in a:
return head
a.add(head)
head=head.next
return None
快慢指针

如上图所示,两个指针同时从head出发,一个指针s每次走一步,一个指针f每次走两步。
若有环则有s的两倍是f走的距离,即 2*(a+b)=a+n*(b+c)+b,所以有a=(n-1)(b+c)+c。其中(b+c)是环的大小,可省略则有a=c,所以s与f相遇后,再来一个指针head从头出发,s指针继续一步一步走,两个相遇的地方就是入环的地方。
若无环则有f为NULL。
所以大循环是f是否为NULL,在循环里再去判断是否有环并找到入环的地方。
//c++
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
if(!head||!head->next) return NULL;
ListNode* f=head;
ListNode* s=head;
while(f)
{
if(!f->next||!f->next->next) return NULL;
f=f->next->next;
s=s->next;
if(f==s)
{
while(s!=head)
{
s=s->next;
head=head->next;
}
return s;
}
}
return NULL;
}
};
#python
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]:
if head==None or head.next==None:
return None
s=head
f=head
while f:
if f.next==None or f.next.next==None:
return None
s=s.next
f=f.next.next
if s==f:
while s!=head:
s=s.next
head=head.next
return s
return None