Leetcode 141 是否存在环型链表 | 刷题打卡

265 阅读3分钟

题目描述

给定一个链表,判断链表中是否有环。

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

如果链表中存在环,则返回 true 。 否则,返回 false 。

进阶: 你能用 O(1)(即,常量)内存解决此问题吗?

示例

示例1:

输入:head = [1,2], pos = 0
输出:true
解释:链表中有一个环,其尾部连接到第一个节点。

示例2:

输入:head = [1,2], pos = 0
输出:true
解释:链表中有一个环,其尾部连接到第一个节点。

示例3:

输入:head = [1], pos = -1
输出:false
解释:链表中没有环。

解题思路

思路一: 借助哈希表

  • 哈希表存储遍历过的节点,每遍历一个节点,都会在哈希表中找是否存在该节点;如果已经存在,就该链表说明存在环;
  • 如果哈希表中不存在该节点,那么就将该节点保存,继续遍历;
  • 如果链表为空,返回false

思路二: 快慢指针

  • 定义两个指针slow 和 fast,从同一个节点出发,slow每次往前走一步,fast每次往前走两步,也就是说 fast 的速度是 slow 的两倍;
  • 如果有环的话,那么slow 和 fast一定会相遇;
  • 如果没有环的话,那么 两个指针就不会相等;

AC代码

题解一: 哈希表

var hasCycle = function(head) {
  let current = head
  let map = new Map()
  while(current) { // 如果头节点存在,就遍历
      if( map.has(current) ) // 判断map中是否存在该节点
          return true // 存在就返回true
      map.set(current, true) // 不存在就将该节点保存为键,值为true
      current = current.next // 继续向下遍历
  }
  return false // 节点不存在,返回false
};

题解二: 快慢指针

var hasCycle = function(head) {
  if(head == null) return false
  let slow = head
  let fast = head
  while(fast != null) {
      if(fast.next == null) { // 节点不存在,说明没有环
          return false
      }
      slow = slow.next // 慢指针往后走一步
      fast = fast.next.next // 快指针往后走两步
      if(fast == slow) { // 快指针跟慢指针相遇
          return true
      }
  }
  return false
};

刷题打卡记录

这是之前的刷题记录,有兴趣的可以看下,如果有什么写的不好的地方还希望大家能够指出;或者到评论区交流学习。

Leetcode15 史上最详细题解之三数之和 | 刷题打卡

Leetcode215 数组中第K个最大的元素 | 刷题打卡

总结

写题解的过程相当于一次反省的过程,加深自己的印象。能够将题解以一种自己所理解的方式写出来的话,那就足够了,并不一定要写的多厉害,人都是会成长的。

加油,hxdm!奥力给!!!

本文正在参与「掘金 2021 春招闯关活动」, 点击查看 活动详情