首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Q142 环形链表 II(Linked List Cycle II)

Q142 环形链表 II(Linked List Cycle II)

作者头像
用户2038589
发布于 2022-05-11 03:04:07
发布于 2022-05-11 03:04:07
23500
代码可运行
举报
文章被收录于专栏:青青天空树青青天空树
运行总次数:0
代码可运行

解析思路

  leetcode 中等难度,题目描述点击这里

  看到题目描述首先蹦出来的解法就是遍历链表,记录走过的节点,当某个节点第二次走到的时候说明该节点就是环的起点,当节点没有下个节点说明没有环。本方法很简单不做详细说明,用一个HashSet记录访问过的节点即可。

  有没有更好的版本呢?当然是有的。通常使用快慢指针的办法来解决这类链表环的问题。思路如下:

  1. 定义两个指针slow(慢指针,每次走1个),fast(快指针,每次走两个),都从head出发。
  2. 每进行一次移动fast和slow间隔的节点就会+1,由此可以推断当slow进入环后,一定会和fast相遇
  3. 假设链表非环的长度为a,环的长度为b,fast走过的距离为f,slow走过的距离为s,当fast在环中循环n次后,fast,slow首次相遇,可得到如下表达式: f=2s(f的速度是s的两倍) f=s+nb(一定比s走的距离多n圈才会相遇) 由上面两个得到:s=nb,由于s走的距离肯定包含了a,可以得到s在环中走的距离为nb-a,只需要继续走a的距离就能刚好走到环的起点。
  4. 所以再加一个指针c从head开始,每次移动一格,当c和slow相遇时说明到了环的起点

java如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.fanxb.common;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

/**
 * 环形链表 II
 * 题目地址:https://leetcode-cn.com/problems/linked-list-cycle-ii/
 * 解题思路:
 *   解法1:只要找到是否某个节点访问了两次即可,用set记录已访问过的节点,当访问的节点在set中说明找到了环形链表头,当节点没有下一个节点说明不存在环
 *   更优化的解法2:
 *     使用快慢指针,定义两个指针slow(慢指针,每次走1个),fast(快指针,每次走两个),都从head出发。
 *     每进行一次移动fast和slow间隔的节点就会+1,由此可以推断当slow进入环后,一定会和fast相遇
 *     假设链表非环的长度为a,环的长度为b,fast走过的距离为f,slow走过的距离为s,当fast在环中循环n次后,fast,slow首次相遇,可得到如下表达式:
 *     f=2s(f的速度是s的两倍)
 *     f=s+nb(一定比s走的距离多n圈才会相遇)
 *     由上面两个得到:s=nb,由于s走的距离肯定包含了a,可以得到s在环中走的距离为nb-a,只需要继续走a的距离就能刚好走到环的起点。
 *     所以再加一个指针c从head开始,每次移动一格,当c和slow相遇时说明到了环的起点
 *
 * @author fanxb
 * Date: 2020/6/9 15:10
 */
public class Q142 {

    public static class ListNode {
        int val;
        ListNode next;

        ListNode(int x) {
            val = x;
            next = null;
        }
    }

    public static ListNode solution(ListNode head) {
        Set<ListNode> set = new HashSet<>();
        while (head != null) {
            if (set.contains(head)) {
                return head;
            } else {
                set.add(head);
                head = head.next;
            }
        }
        return null;
    }

    public static ListNode betterSolution(ListNode head) {
        ListNode slow = head, fast = head;
        do {
            if (fast == null || fast.next == null) {
                return null;
            }
            slow = slow.next;
            fast = fast.next.next;
        } while (slow != fast);
        //此时快慢指针相遇,再加一个指针c
        ListNode c = head;
        while (c != slow) {
            slow = slow.next;
            c = c.next;
        }
        return c;
    }

}

本体存在一些变体也是一样的解法,

比如找到开始节点后的第n个节点,可在找到头后再遍历n次

比如找到开始节点前的第n个节点,一样的找到头后,再遍历一遍环得到环长度,再计算出需要遍历的次数,得到距离开始节点前的第n个节点

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-03-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
[Leetcode][python]Linked List Cycle/Linked List Cycle II/环形链表/环形链表 II
我们可以通过检查一个结点此前是否被访问过来判断链表是否为环形链表。常用的方法是使用哈希表。
蛮三刀酱
2019/03/26
6500
[Leetcode][python]Linked List Cycle/Linked List Cycle II/环形链表/环形链表 II
力扣142——环形链表 II
为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。
健程之道
2020/02/12
2800
力扣142——环形链表 II
LeetCode142题 环形链表 II(Linked List Cycle II)
题目描述: 给定一个链表,返回链表开始入环的第一个节点。如果链表无环,则返回 null。 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。 说明:不允许修改给定的链表。
code随笔
2020/04/14
2960
LeetCode142题 环形链表 II(Linked List Cycle II)
leetcode-142. 环形链表 II
  根据题目要求,我们可以想到可以利用 set 不可重复的性质来完成这道题。定义一个 HashSet 集合且新建一个节点 cur 并让 cur 指向传进来链表的头节点 head,用 while 循环将链表上每一个点都逐一加入 set 中,只要不重复且不到链表尾部,都可以正常加入 set 中,若到了链表尾部都没有冲突出现,则证明这个链表不含环,若出现冲突,则说明含环,并返回起冲突的节点,此时这个节点就是环的第一个节点。
灰太狼学Java
2022/10/27
2100
leetcode-142. 环形链表 II
LeetCode 142:环形链表 II Linked List Cycle II
为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。
爱写bug
2019/07/17
5320
链表——142. 环形链表 II
给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
向着百万年薪努力的小赵
2022/12/02
1890
链表——142. 环形链表 II
142. 环形链表 II
为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。注意,pos 仅仅是用于标识环的情况,并不会作为参数传递到函数中。
名字是乱打的
2021/12/23
2690
142. 环形链表 II
环形链表II的解法与一些证明!
如果链表无环,则返回 null。为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。
五分钟学算法
2023/01/10
6220
环形链表II的解法与一些证明!
链表中环的入口节点
这里使用最经典的快慢指针解法,两个指针同时前进,慢指针一次走一步,快指针一次走两步,若链表存在环,则二者一定会有相遇的机会。若不存在环,则由于快指针走的比较快则会先到达空指针。
doper
2022/09/26
1.5K0
链表中环的入口节点
图解LeetCode——142. 环形链表 II
给定一个链表的头节点  head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
爪哇缪斯
2023/05/19
1810
图解LeetCode——142. 环形链表 II
单链表之环形链表
不论在面试或者刷题过程中,很大概率都会遇到环形链表这种类型的题目,例如 leetcode 141. 环形链表 以及 leetcode 142. 环形链表 II 等,本文主要介绍通过快慢指针法来解决此类题型,以供大家参考。
程序员小熊
2021/05/28
5350
单链表之环形链表
数据结构之环形链表的有关解法
如下图:那么为什么快慢指针会相遇呢?(下图中快指针一次移动2步,慢指针一次移动1步)
用户11289931
2024/09/24
1310
数据结构之环形链表的有关解法
环形链表找入口,真的太妙了
链表是否有环问题看似简单,但实际处理上有很多需要注意的,这个问题是非常高频笔试面试题,记忆不牢固容易遗忘,可以认真看看学习一波!当然今天这两题对应力扣141和力扣142,有个小伙伴就在某手面试中遇到了。
bigsai
2021/06/25
1.7K0
环形链表找入口,真的太妙了
【一天一大 lee】环形链表II (难度:中等) - Day20201010
给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
前端小书童
2020/10/26
2850
【一天一大 lee】环形链表II (难度:中等) - Day20201010
单链表的六大解题套路,你都见过么?
上次在视频号直播,跟大家说到单链表有很多巧妙的操作,本文就总结一下单链表的基本技巧,每个技巧都对应着至少一道算法题:
labuladong
2021/09/23
3500
LeetCode题解—链表中环的检测
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 pos为环的起点位置。
码上积木
2021/03/10
1.3K0
环形链表 II ( LeetCode 142 )
如果链表无环,则返回 null。为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。
五分钟学算法
2021/12/21
4490
环形链表 II ( LeetCode 142 )
环形链表问题(判环+寻找入环点)
给你一个链表的头节点 head ,判断链表中是否有环。如果链表中存在环 ,则返回 true 。 否则,返回 false 。
YIN_尹
2024/04/10
2020
环形链表问题(判环+寻找入环点)
链表中环的入口结点
1、遍历单链表的每个结点 2、如果当前结点地址没有出现在set中,则存入set中 3、否则,出现在set中,则当前结点就是环的入口结点 4、整个单链表遍历完,若没出现在set中,则不存在环
MickyInvQ
2021/12/07
6250
链表中环的入口结点
LeetCode之链表(10)
今天有点闲,就来连刷几道题,下次不这样干了,有点hold不住,建议以后保持平衡刷题规律!
公众号guangcity
2019/09/20
4160
LeetCode之链表(10)
相关推荐
[Leetcode][python]Linked List Cycle/Linked List Cycle II/环形链表/环形链表 II
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验