描述

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

说明:不允许修改给定的链表。

进阶

你是否可以不用额外空间解决此题?

解法一:哈希表

思路

最直接的解法就是利用一个集合保存每次遍历的节点的引用。之后,从链表头开始遍历,每遍历一个节点,就判断该节点的引用是否在集合中,如果不在集合中,则将该节点的引用放入集合中;如果在集合中,则返回该节点的引用(环的入口)。当然,如果能遍历到链表尾部,此时链表无环,返回 null

Java 实现

/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/ import java.util.Set;
import java.util.HashSet; public class Solution {
public ListNode detectCycle(ListNode head) {
ListNode curr = head;
Set<ListNode> nodesSeen = new HashSet<>();
while (curr != null) {
if (nodesSeen.contains(curr)) {
return curr;
}
nodesSeen.add(curr);
curr = curr.next;
}
return curr;
}
}

Python 实现

# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None class Solution(object):
def detectCycle(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
curr = head
nodes_seen = set()
while curr:
if curr in nodes_seen:
return curr
nodes_seen.add(curr)
curr = curr.next
return curr

复杂度分析

  • 时间复杂度:\(O(n)\)
  • 空间复杂度:\(O(n)\)

解法二:双指针

思路

LeetCode 第 141 题一样,如果不想占用额外的空间的话,可以采用双指针的方式。

假设链表的起始节点为 A,环的入口节点为 B,两个指针(快慢指针)相交节点为 C,AB 两点之间的长度为 \(x\),BC 两点之间的长度为 \(y\),CB 两点之间的长度为 \(z\)。慢指针 slow 走过的长度为 \(x+y\),快指针 fast 为了“赶上”慢指针,应该走过的长度为 \(x + y + z + y\),同时,由于快指针的速度是慢指针的两倍,因此相同时间内,快指针走过的路程应该是慢指针(走过的路程)的两倍,即

\[x + y + z + y = 2 (x + y)
\]

化简得,

\[x = z
\]

因此,如果此时有另外一个慢指针 slow2 从起始节点 A 出发,则两个慢指针会在节点 B (环的入口)相遇。

Java 实现

/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/ public class Solution {
public ListNode detectCycle(ListNode head) {
ListNode slow = head, fast = head;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next; if (slow == fast) {
ListNode slow2 = head;
while (slow != slow2) {
slow = slow.next;
slow2 = slow2.next;
}
return slow;
}
}
return null;
}
}
// Runtime: 1 ms
// Your runtime beats 100.00 % of python submissions.

Python 实现

# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None class Solution(object):
def detectCycle(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
slow, fast = head, head
while fast and fast.next:
slow = slow.next
fast = fast.next.next if slow == fast:
slow2 = head
while slow != slow2:
slow = slow.next
slow2 = slow2.next
return slow
return None
# Runtime: 44 ms
# Your runtime beats 99.73 % of python submissions.

复杂度分析

  • 时间复杂度:\(O(n)\),其中 \(n\) 表示链表的长度。最坏的情况下(链表有环),需要迭代的次数为 \(x + y + z = n\) 次,因此时间复杂度为 \(O(n)\)
  • 空间复杂度:\(O(1)\),只需要存储 3 个引用

【LeetCode题解】142_环形链表2(Linked-List-Cycle-II)的更多相关文章

  1. Leetcode 141题 环形链表(Linked List Cycle) Java语言求解

    题目描述: 给定一个链表,判断链表中是否有环. 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始). 如果 pos 是 -1,则在该链表中没有环. Map ...

  2. [LeetCode题解]142. 环形链表 II | 快慢指针

    解题思路 本题是在141. 环形链表基础上的拓展,如果存在环,要找出环的入口. 如何判断是否存在环,我们知道通过快慢指针,如果相遇就表示有环.那么如何找到入口呢? 如下图所示的链表: 当 fast 与 ...

  3. LeetCode 141. 环形链表(Linked List Cycle)

    题目描述 给定一个链表,判断链表中是否有环. 进阶:你能否不使用额外空间解决此题? 解题思路 快慢指针,慢指针一次走一步,快指针一次走两步,若两者相遇则说明有环,快指针无路可走则说明无环. 代码 /* ...

  4. [LeetCode题解]141. 环形链表 | 快慢指针

    题目描述 给定一个链表,判断链表中是否有环. 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环. 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的 ...

  5. [LeetCode]题解(python):142-Linked List Cycle II

    题目来源: https://leetcode.com/problems/linked-list-cycle-ii/ 题意分析: 给定一个链表,如果链表有环,返回环的起始位置,否则返回NULL.要求常量 ...

  6. 【链表】Linked List Cycle II

    题目: Given a linked list, return the node where the cycle begins. If there is no cycle, return null. ...

  7. LeetCode 142. 环形链表 II(Linked List Cycle II)

    142. 环形链表 II 142. Linked List Cycle II 题目描述 给定一个链表,返回链表开始入环的第一个节点.如果链表无环,则返回 null. 为了表示给定链表中的环,我们使用整 ...

  8. [LeetCode] Linked List Cycle II 单链表中的环之二

    Given a linked list, return the node where the cycle begins. If there is no cycle, return null. Foll ...

  9. [LeetCode] 142. Linked List Cycle II 单链表中的环之二

    Given a linked list, return the node where the cycle begins. If there is no cycle, return null. To r ...

  10. [算法][LeetCode]Linked List Cycle & Linked List Cycle II——单链表中的环

    题目要求 Linked List Cycle Given a linked list, determine if it has a cycle in it. Follow up: Can you so ...

随机推荐

  1. asp.net接收传入的数据流

    我们在日常的应用中,都会遇到这样一个问题,就是我们做的asp.NET程序,会收到其它第三方软件传过来的一些信息数据流,当然了一些文本形式的信息,可以采用get或post的方法来接收,可是要是传过来的是 ...

  2. Swagger中显示注释

    Webapi中Swagger中不显示注解的解决方法 1.找见生成项目时候生成的xml文件.查看存放路劲方法: 右键项目-->点击属性-->在属性中选择“生成”就能看见xml文件存放路径: ...

  3. 基于vs2012的C# winform抽奖小程序的总结

    哈希表的使用 Hashtable hashtable = new Hashtable(); hashtable.ContainsValue(tmp);//判断哈希表中有没有tmp hashtable. ...

  4. C#基础复习(2) 之 装箱拆箱

    参考资料 [1] @只增笑耳Jason的回答 https://www.zhihu.com/question/57208269 [2] <C# 捷径教程> 疑难解答 装箱和拆箱是什么? 何时 ...

  5. oracle12c不能进入到http://localhost:1158/em的解决办法

    oracle12c的em经过精简,比11g小 很多,登陆方式也发生了变化,原来的https://localhost:1158/em或者https://localhost:1158/em登陆总是会遇到问 ...

  6. PageAdmin CMS网站制作教程实例:如何制作一个报名表?

    PageAdmin CMS网站建设实例:如何制作一个报名表? 有时我们根据需求需要制作一些自定义表,该如何去制作呢? 我们以制作一个报名表为例: 登录后台地址,进入后台, 2.在顶部导航中找到系统,并 ...

  7. Java并发编程读书笔记(一)

    ----------------------------------------------<Java并发编程实战>读书笔记-------------------------------- ...

  8. CentOS 7 - 最小化安装以及引发的问题!

    一,操作系统和虚拟机 操作系统:CentOS 7 官方网站:https://www.centos.org 下载地址:https://www.centos.org/download/ 下载版本分三个:D ...

  9. 五,mysql优化——sql语句优化小技巧

    1,大批量插入数据 (1)对于MyISAM: alter table table_name disable keys; loading data; alter table table_name ena ...

  10. 微信小程序与vueJs的异同

    简而言之,所有的框架都是建立在原生javascript基础之上的,所以对于有一定js基础的同学来说,各种框架都是比较容易入手的,但不同的框架之间又有一定的差别,有时候切换使用时就会掉入坑了. 一.微信 ...