【面试经典题】判断链表是否有环| 8月更文挑战

817 阅读2分钟

这是我参与8月更文挑战的第7天,活动详情查看:8月更文挑战

想要坚持写点什么,那干脆写一个系列吧。想想有什么可以写的呢?程序=算法+数据结构,可见算法的重要性。这个系列老诗力求用最简单的语言把算法讲得明明白白,由浅到深,有兴趣的话,可以关注一下专栏。

上一篇文章写了链表的基本操作,包括新建链表,插入链表节点,删除链表节点,查询链表结点等内容。 现在这一篇是讲如何判断链表是否有环的算法。面试中这一题目是比较常见的。

快慢指针判断法

对于这个问题我们可以采用“快慢指针”的方法。就是有两个指针fast和slow,开始的时候两个指针都指向链表头head,然后在每一步操作中slow向前走一步即:slow = slow->next,而fast每一步向前两步即:fast = fast->next->next。由于fast要比slow移动的快,如果有环,fast一定会先进入环,而slow后进入环。当两个指针都进入环之后,经过有限的操作次数之后,快慢指针是必定会相遇的。

具体代码如下:

//快慢指针判断是否有环 
bool exitLoop(Node *head) 
{ 
    Node *fast, *slow ; 
    slow = fast = head ; 
   
    while (slow != NULL && fast -> next != NULL) 
    { 
        slow = slow -> next ; 
        fast = fast -> next -> next ; 
        if (slow == fast) 
            return true ; 
    } 
    return false ; 
} 

22222.png

如上图所示

也就是说,slow每次向前走一步,fast向前追了两步,因此每一步操作后fast到slow的距离缩短了1步,这样继续下去就会使得两者之间的距离逐渐缩小:...、5、4、3、2、1、0 -> 相遇。又因为在同一个环中fast和slow之间的距离不会大于换的长度,因此到二者相遇的时候slow一定还没有走完一周(或者正好走完以后,这种情况出现在开始的时候fast和slow都在环的入口处)。

想要学习更多算法问题,或者要更多项目源码,请移步到公众号:诗一样的代码

既然进来了,原创不易。小伙伴点个赞再走呗