[路飞]_面试题 02.08. 环路检测

141 阅读2分钟

「这是我参与2022首次更文挑战的第26天,活动详情查看:2022首次更文挑战

面试题 02.08. 环路检测

给定一个链表,如果它是有环链表,实现一个算法返回环路的开头节点。若环不存在,请返回 null。

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。

「示例1:」

circularlinkedlist.png

输入:head = [3,2,0,-4], pos = 1
输出:tail connects to node index 1
解释:链表中有一个环,其尾部连接到第二个节点。
「示例2:」

2.png

输入:head = [1,2], pos = 0
输出:tail connects to node index 0
解释:链表中有一个环,其尾部连接到第一个节点。
「示例3:」

3.png

输入:head = [1], pos = -1
输出:no cycle
解释:链表中没有环。
提示:
  • 你是否可以不用额外空间解决此题?

解题思路

1. 我们可以使用快慢指针,通过while循环来判断当前链表是否有环
2. 如果快慢指针在while循环里面相遇了,则说明有环,否则就是无环
3. 当前快慢指针相等的时候,我们可以声明一个cur指针,指向链表头部,让慢指针和快指针同时移动,当他们两个相等的时候,cur指针的值就是环状开始的节点的位置

代码实现

/**
 * 面试题 02.08. 环路检测
 * @param {ListNode} head
 * @return {ListNode}
 */
var detectCycle = function (head) {
  let slow = head;
  let fast = head;
  while (slow && fast && fast.next) {
    slow = slow.next;
    fast = fast.next.next;
    if (fast == null) return null;
    if (fast == slow) {
      let cur = head;
      while (slow != cur) {
        slow = slow.next;
        cur = cur.next;
      }
      return cur;
    }
  }
  return null;
};

如果你对这道题目还有疑问的话,可以在评论区进行留言;