Leetcode HOT 100 ——141&142 环形链表

119 阅读2分钟

Leetcode HOT 100 ——141&142 环形链表

链表

题目描述

给你一个链表的头节点 head ,判断链表中是否有环。

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达。

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

**进阶:**你是否可以使用 O(1) 空间解决此题?

解题思路

快慢双指针 和 环形追击问题

快指针一次走两步,慢指针一次走一步,在环中肯定能相遇

解题代码

第一种解法 哈希表

每次遍历一个节点,就判断这个节点是否在表中。如果存在就说明存在环。

因为使用了哈希表,所以空间复杂度为 O(n)

var hasCycle = function(head) {
  let map = new Set()
  let cur = head
  while(cur) {
    if(map.has(cur)) return true
    map.add(cur)
    cur = cur.next
  }
  return false
};

第二种解法 快慢指针

龟兔赛跑算法

快指针一次走两步,慢指针一次走一步,当两指针相遇说明存在环。

var hasCycle = function(head) {
  let fast = head, slow = head
  while(fast && fast.next && fast.next.next) {
    fast = fast.next.next
    slow = slow.next
    if(fast === slow) return true
  }
  return false
};

扩展题目:142 环形链表II

这道题是141的扩展题,不同的是,要返回入环的第一个节点

题目描述

给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。

不允许修改链表。

进阶: 你是否可以使用 O(1) 空间解决此题?

解题代码

var detectCycle = function(head) {
  let slow = head, fast = head, exist = false
  while(fast && fast.next && fast.next.next) {
    slow = slow.next
    fast = fast.next.next
    if(fast === slow) {
      exist = true
      break
    }
  }
  if(exist) {
    slow = head
    while(slow !== fast) {
      slow = slow.next
      fast = fast.next
    }
    return slow
  }
  return null
};