leetcode每天一题:【环形链表】(简单)

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

题目描述

leetcode题目地址

给你一个链表的head节点,然后你需要判断这个链表是否有环。

怎样代表这个链表有环?

就是这个链表中有节点的next又指向了这个链表的之前一个节点,导致链表闭环了,这样就说这个链表有环。

如果有环就返回true, 否则就返回false

画个图说明下:

这个就有环的链表(闭环了,节点3又转到节点2了)

image.png

这个链表就没有环

image.png

思路分析

第一种方法

我们可以对链表进行遍历(链表没有现成的遍历方法,采用递归遍历),遍历一次就当前节点push到数组中。

另外每次push前都要先判断数组中是否存在该节点,如果有该节点,则代表着有环,返回true即可。

如果遍历的过程中,发现当前节点为null的时候,则代表链表没有环,已经到末尾了。返回false即可。

代码如下:

/**
 * Definition for singly-linked list.
 * function ListNode(val) {
 *     this.val = val;
 *     this.next = null;
 * }
 */

/**
 * @param {ListNode} head
 * @return {boolean}
 */
var hasCycle = function (head) {
  const arr = []
  function check (list) {
    if (!list) return false
    while (list) {
      if (arr.includes(list)) return true
      arr.push(list)
      return check(list.next)
    }
  }
  return check(head)
};
复制代码

image.png

这样写,通过是通过了,但是耗时有点久。

优化版

怎么优化呢?

因为这个是通过数组来判断是否存在的,如果数据一多,导致耗时就会变长。

我们可以对数组做个优化,使用map来存储。节点为key,true为value。

通过map来寻找节点,相比数据会更快。

代码如下:

/**
 * Definition for singly-linked list.
 * function ListNode(val) {
 *     this.val = val;
 *     this.next = null;
 * }
 */

/**
 * @param {ListNode} head
 * @return {boolean}
 */
var hasCycle = function (head) {
  const map = new Map()
  function check (list) {
    if (!list) return false
    while (list) {
      if (map.get(list)) return true
      map.set(list, true)
      return check(list.next)
    }
  }
  return check(head)
};
复制代码

image.png

相比数组,map带来的提升是显而易见的。

再再优化

我们可以使用双指针法再次优化。

一个快指针指向当前节点的next节点,一个慢指针指向当前节点。

while循环遍历,快指针一次移动2步,慢指针一次移动1步,如果发现快指针和慢指针相等了,则代表着快指针跑多了一圈,代表有环,不然无法相等。

如果发现快指针为null或者快指针的next节点为null时,则代表没有环,返回false即可。

代码如下:

/**
 * Definition for singly-linked list.
 * function ListNode(val) {
 *     this.val = val;
 *     this.next = null;
 * }
 */
/**
 * @param {ListNode} head
 * @return {boolean}
 */
var hasCycle = function (head) {
  if (!head) return false
  let slow = head
  let fast = head.next

  while (slow !== fast) {
    if (!fast || !fast.next) {
      return false
    }
    slow = slow.next
    fast = fast.next.next
  }
  return true
};
复制代码

image.png

Guess you like

Origin juejin.im/post/7068095413974204453