这是我参与8月更文挑战的第8天,活动详情查看:8月更文挑战
想要坚持写点什么,那干脆写一个系列吧。想想有什么可以写的呢?程序=算法+数据结构,可见算法的重要性。这个系列老诗力求用最简单的语言把算法讲得明明白白,由浅到深,有兴趣的话,可以关注一下专栏。
上两篇文章写了链表的基本操作,包括新建链表,插入链表节点,删除链表节点,查询链表结点等内容。然后上一篇文章写的是如何判断链表是否有环。接下来我们再深入思考一下,如何找到链表的入口。面试中也会有考官会问到的。
快慢指针判断法
我们可以用数学公式推断出:从链表起点head开始到入口点的距离a,与从slow和fast的相遇点到入口点的距离相等。这有兴趣的同学可以自己去检验一下。如果没有兴趣检验的同学,可以记住这一个结论。
源码实现
//快慢指针,找出环的入口
Node* findLoopStart(Node *head)
{
Node *fast, *slow ;
slow = fast = head ;
while (slow != NULL && fast -> next != NULL)
{
slow = slow -> next ;
fast = fast -> next -> next ;
if (slow == fast) break ;
}
if (slow == NULL || fast -> next == NULL) return NULL ; //没有环,返回NULL值
Node * ptr1 = head ; //链表开始点
Node * ptr2 = slow ; //相遇点
while (ptr1 != ptr2)
{
ptr1 = ptr1 -> next ;
ptr2 = ptr2 -> next ;
}
return ptr1 ; //找到入口点
}
上面的代码,先是用快慢指针判断出有没有环,如果没有环的话,那就直接返回null值,如果有环的话继续下面的操作。
通过快慢指针,我们可以得出它们的相遇点。剩下的就是让ptr1=head和ptr2相遇点的慢指针继续往前走就行了。因为他们相遇的点那就是环的入口点。
想要学习更多算法问题,或者要更多项目源码,请移步到公众号:诗一样的代码。
既然进来了,原创不易。小伙伴点个赞再走呗。