问题:
1:判断链表有没有环
//head指向链表第一个节点
int hasRing(ListNode* head){
if(head==NULL){
return ;
}
ListNode*p=head;
ListNode*c=head;
while(c!=NULL&&c->next!=NULL){//偶数个节点时由第一个条件结束
p=p->next;//慢指针 //奇数个节点时由第二个条件结束
c=c->next->next;//快指针
if(c==p){//如果慢与快能再一次重合,则有环
return 1;
}
}
return 0;
}
2:已知链表有环,求环的节点数
//head指向链表第一个节点
int nodeNumber(ListNode* head){
ListNode*p=head;//慢指针
ListNode*c=head;//快指针
while(1){//有环一定不会遇到NULL,不用条件
p=p->next;
c=c->next->next;
if(p==c){//慢与快指针相遇时一定在环中
break;
}
}
int co=0;
while(1){
p=p->next;
co++;
if(p==c){//再次相遇时循环次数等于环的节点数
break;
}
}
return co;
}
3:已知链表有环,求环入口的节点值
//head指向链表第一个节点
int entryVal(ListNode* head){
int n=nodeNumber(head);//求环的节点数
ListNode*p=head;
ListNode*c=head;
while(n--){//让p领先c环节点数个位置
p=p->next;
}
while(p!=c){//再次相遇时一定在环的入口,因为它们起始差环节点数个位置
p=p->next;
c=c->next;
}
return p->val;
}
//head指向链表第一个节点
int entryVal(ListNode* head){
ListNode*p=head;
ListNode*c=head;
while(1){//快比慢多走n圈,快走的路程是慢的两倍,所以慢走了n圈环的长度
p=p->next;//慢指针
c=c->next->next;//快指针
if(c==p){
break;
}
}
p=head;
while(p!=c){//一个从相遇点走,一个从头走,会再次在该相遇点相遇,此时速度相同,一定在环入口相遇
p=p->next;
c=c->next;
}
return c->val;
}