判断一个链表是否有环 && 找到环的入口

文章目录

  • 题目
  • 解题思路
  • 代码

题目

  • 设计一个算法完成以下功能:判断一个链表是否有环,如果有,找出换的入口且返回,否则返回NULL

解题思路

  • 根据题意分析第一次相遇的情况,如图所示:(首先假设是有环的,因无环的情况不会相遇,可直接排除)判断一个链表是否有环 && 找到环的入口_第1张图片

  • soft指针和fast指针在红点处相遇,起点距离环入点为a,相遇点距离入点距离为x,L为环的长度,可得到方程:
    2 × ( a + x ) = n × L + a + x 2\times (a+ x )= n\times L +a+x 2×(a+x)=n×L+a+x
    化简得: a + x = n × L a+ x = n\times L a+x=n×L

  • 此时,让一个p1指向起点,p2指向相遇点,p1与p2速度保持一致,每次均移动一个位置进行遍历,对他俩的相遇时情况进行分析:判断一个链表是否有环 && 找到环的入口_第2张图片

  • 两者速度保持一致,当p1到达了入口时,行走距离为a,p2距离入点的距离为(x + a = n × L)%L=0,即:p2也到达入点,p1、p2在入口处相遇。

代码

  • 以C为例
    LNode* FindLoopStart(LNode *head)
    {
    	LNode* fast=head,*slow=head;
    	while(slow!=NULL && fast->next!=NULL)
    	{
    		slow=slow->next;//每次走一步
    		fast=fast->next;
    		//此处修改
    		if(fast->next != NULL)//每次走两步
    			fast=fast->next;
    		if(slow==fast) break;//相遇
    	}	
    	if(slow==NULL || fast->next==NULL)
    		return NULL;//无环返回NULL
    	LNode *p1=head,*p2=slow;//分别指向起点和相遇点
    	while(p1!=p2)
    	{
    		p1=p1->next;
    		p2=p2->next;
    	}
    	return p1;//返回入口
    }
    

你可能感兴趣的:(C#)