第一种是比较聪明的方法,高赞方法
一个快指针runner,一个慢指针walker,快指针一次走两步,慢指针一次走一步。
(另:这种方法可以找到链表的中间节点),如果说链表有环,那么最终runner和walker会相等。
bool hasCycle(ListNode *head) {
if(head==NULL||head->next==NULL) return false;
ListNode *A=head,*B=head;
while(1){
if(A->next!=NULL) A=A->next;
else return false;
if(B->next==NULL) return false;
else if(B->next->next==NULL) return false;
else B=B->next->next;
if(A==B) return true;
}
return false;
}
也可以用set元素的唯一性,我只要第一次出现重复的指针,就可以判断有环了。
这种方法看上去比较简单,效率没有第一种方法高。
bool hasCycle(ListNode *head) {
ListNode *p=head;
set<ListNode*> s;
while(p){
if(s.count(p)) return true;
s.insert(p);
p=p->next;
}
return false;
}
同样我们可以用set这种方法找出环的起始节点在哪里,只不过是返回值变化一下。
ListNode *detectCycle(ListNode *head) {
ListNode *p=head;
set<ListNode*> s;
while(p){
if(s.count(p)) return p;
s.insert(p);
p=p->next;
}
return NULL;
}