环形链表基本问题——如何判断链表是否成环?

真题描述:给定一个链表,判断链表中是否有环。

输入:[3,2,0,4](链表结构如下图) 输出:true
解释:链表中存在一个环
环形链表 - 图1

思路解读

其实链表成环的特征非常明显,大家可以结合一个现实中的例子来理解:
假如现实中有一个长跑爱好者李雷,这货很狂,他立了一个 flag,说要徒步环游世界:
环形链表 - 图2

这样,不管李雷走完这个环用了多少年,世事如何变迁,只要他的 flag 还没有倒,那么李雷就一定能回到自己梦开始的地方:)。
换个角度看:只要李雷在闷头前进的过程中,发现了 flag 的存在,那么就意味着,李雷确实走了一个环。毕竟若这是一条线,他将永远无法回到起点。
回到链表的世界里,也是一个道理。一个环形链表的基本修养,是能够让遍历它的游标回到原点:

环形链表 - 图3

  1. var hasCycle = function(head) {
  2. while(head) {
  3. if(head.flag) {
  4. return true
  5. }
  6. head.flag = true;
  7. head = head.next
  8. }
  9. return false
  10. };

环形链表衍生问题——定位环的起点

真题描述:给定一个链表,返回链表开始入环的第一个结点。 如果链表无环,则返回 null。

示例 1:

输入:head = [3,2,0,-4](如下图) 输出:tail connects to node index 1 解释:链表中有一个环,其尾部连接到第二个结点。

环形链表 - 图4
输入:head = [1,2](如下图)
输出:tail connects to node index 0

环形链表 - 图5