算法的学习笔记—链表中环的入口结点(牛客JZ23)

news2024/11/27 4:21:42

img

😀前言
在链表的操作中,环形链表是一个常见且需要特别处理的结构。当我们遇到一个包含环的链表时,如何找到环的入口结点是一个经典的问题。本文将详细介绍使用双指针技术来解决这一问题,并提供一个基于 Java 的实现代码。

🏠个人主页:尘觉主页

文章目录

  • 😊链表中环的入口结点
    • 😍题目描述
      • 💞输入描述:
      • 💞返回值描述:
    • 😋示例
      • 示例1
      • 示例2
      • 示例3
    • 😃解题思路
      • 😀解题思路2
      • 💗代码实现
      • 💕性能分析
      • 💕原理解析
    • 😄总结

😊链表中环的入口结点

NowCoder

😍题目描述

给一个长度为n链表,若其中包含环,请找出该链表的环的入口结点,否则,返回null。

数据范围: n≤10000,1<=结点值<=10000

要求:空间复杂度 O(1),时间复杂度 O(n)

例如,输入{1,2},{3,4,5}时,对应的环形链表如下图所示:

img

可以看到环的入口结点的结点值为3,所以返回结点值为3的结点。

💞输入描述:

输入分为2段,第一段是入环前的链表部分,第二段是链表环的部分,后台会根据第二段是否为空将这两段组装成一个无环或者有环单链表

💞返回值描述:

返回链表的环的入口结点即可,我们后台程序会打印这个结点对应的结点值;若没有,则返回对应编程语言的空结点即可。

😋示例

示例1

输入:{1,2},{3,4,5}
返回值:3
说明:返回环形链表入口结点,我们后台程序会打印该环形链表入口结点对应的结点值,即3

示例2

输入:{1},{}
返回值:“null”
说明:没有环,返回对应编程语言的空结点,后台程序会打印"null"

示例3

输入:{},{2}
返回值:2
说明:环的部分只有一个结点,所以返回该环形链表入口结点,后台程序打印该结点对应的结点值,即2

😃解题思路

使用双指针,一个快指针 fast 每次移动两个节点,一个慢指针 slow 每次移动一个节点。因为存在环,所以两个指针必定相遇在环中的某个节点上。

假设环入口节点为 y1,相遇所在节点为 z1

假设快指针 fast 在圈内绕了 N 圈,则总路径长度为 x+Ny+(N-1)zz 为 (N-1) 倍是因为快慢指针最后已经在 z1 节点相遇了,后面就不需要再走了。

而慢指针slow总路径长度为 x+y

因为快指针是慢指针的两倍,因此 x+Ny+(N-1)z = 2(x+y)

我们要找的是环入口节点 y1,也可以看成寻找长度 x 的值,因此我们先将上面的等值分解为和 x 有关:x=(N-2)y+(N-1)z

上面的等值没有很强的规律,但是我们可以发现 y+z就是圆环的总长度,因此我们将上面的等式再分解:x=(N-2)(y+z)+z。这个等式左边是从起点x1 到环入口节点 y1 的长度,而右边是在圆环中走过 (N-2) 圈,再从相遇点 z1 再走过长度为 z 的长度。此时我们可以发现如果让两个指针同时从起点 x1 和相遇点 z1 开始,每次只走过一个距离,那么最后他们会在环入口节点相遇。

😀解题思路2

解决这个问题的关键在于如何有效地检测链表中的环,并找到环的入口结点。我们可以使用一种被称为快慢指针的技术来实现。

  1. 快慢指针的移动: 我们设置两个指针 slowfast,其中 slow 每次移动一个节点,而 fast 每次移动两个节点。如果链表中存在环,两个指针最终会在环内相遇。
  2. 确定相遇点:slowfast 相遇时,说明链表中存在环。此时,fast 指针已经绕环走了一圈或多圈,而 slow 则走了半圈。
  3. 找到环的入口: 相遇后,我们将 fast 指针移回链表头部,并让 slowfast 同步移动,每次移动一个节点。最终,它们会在环的入口处相遇,此时的节点即为我们要找的环的入口结点。

💗代码实现

以下是基于上述思路的 Java 代码实现:

public class Solution {
    public ListNode EntryNodeOfLoop(ListNode pHead) {
        // 如果链表为空或只有一个节点,直接返回 null
        if (pHead == null || pHead.next == null)
            return null;

        // 初始化慢指针 slow 和快指针 fast
        ListNode slow = pHead, fast = pHead;

        // 使用 do-while 循环来保证 slow 和 fast 至少移动一次
        do {
            // 快指针每次移动两步,慢指针每次移动一步
            fast = fast.next.next;
            slow = slow.next;
        } while (slow != fast);  // 直到两个指针相遇

        // 将快指针移回链表头部
        fast = pHead;

        // 快慢指针同时移动,直到相遇在环的入口处
        while (slow != fast) {
            slow = slow.next;
            fast = fast.next;
        }

        // 返回相遇的节点,即环的入口节点
        return slow;
    }
}

💕性能分析

该算法的时间复杂度为 O(n),因为无论链表长度如何,slowfast 最多只需要遍历链表两次。空间复杂度为 O(1),因为我们只使用了两个额外的指针,没有占用额外的存储空间。

💕原理解析

在这段代码中,我们首先通过快慢指针的相遇来判断链表是否存在环。当我们确定存在环时,将 fast 指针移回链表头部,并再次与 slow 同步移动。在它们相遇的地方,即是环的入口结点。这种方法利用了快慢指针的速度差和链表的结构特性,能够高效地找到环的入口。

😄总结

通过使用快慢指针技术,我们可以高效地检测链表中的环,并找到环的入口结点。这种方法简单明了,同时具备良好的时间和空间复杂度表现。在处理链表相关问题时,快慢指针是一种非常实用的工具,希望本文的讲解能够帮助你更好地理解和解决链表中的环问题。

😁热门专栏推荐
想学习vue的可以看看这个

java基础合集

数据库合集

redis合集

nginx合集

linux合集

手写机制

微服务组件

spring_尘觉

springMVC

mybits

等等等还有许多优秀的合集在主页等着大家的光顾感谢大家的支持

🤔欢迎大家加入我的社区 尘觉社区

文章到这里就结束了,如果有什么疑问的地方请指出,诸佬们一起来评论区一起讨论😁
希望能和诸佬们一起努力,今后我们一起观看感谢您的阅读🍻
如果帮助到您不妨3连支持一下,创造不易您们的支持是我的动力🤞

img

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2045018.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

搭建内网开发环境(五)|基于nexus搭建npm私服

引言 在前面一篇教程中&#xff0c;通过 nexus 搭建了 maven 的私服&#xff0c;并通过脚本将本地的依赖文件批量上传到私服中&#xff0c;本文介绍通过 nexus 搭建 npm 私服&#xff0c;同样也通过脚本将本地依赖文件同步到私服中。 搭建内网开发环境&#xff08;一&#xff…

目标检测 | yolov6 原理和介绍

前言&#xff1a;目标检测 | yolov5 原理和介绍 后续&#xff1a; 1.简介 YOLOv6是由美团视觉智能部研发的一款目标检测框架&#xff0c;专注于工业应用&#xff0c;致力于提供极致的检测精度和推理效率。相较于YOLOv4和YOLOv5&#xff0c;YOLOv6在网络结构方面进行了深入优化…

动手学深度学习(pytorch)学习记录12-激活函数[学习记录]

激活函数 激活函数&#xff08;activation function&#xff09;通过计算加权和并加上偏置来确定神经元是否应该被激活&#xff0c; 它们将输入信号转换为输出的可微运算。 import torch import matplotlib.pyplot as plt 简单定义一个画图的函数 def graph_drawing(x_,y_…

Robotics: Aerial Robotics 部分笔记——Week3(2)规划部分

3.2 轨迹不同于路径&#xff0c;需要是光滑的&#xff0c;考虑无人机动力学约束三阶导控制jerk&#xff0c;四阶导控制snap如果轨迹要满足某个特点&#xff0c;如&#xff1a;最短时间、最短路径&#xff0c;此时最优控制思路会被引入&#xff0c;变分法等算法可用以求解,选择…

2024最新版本Python安装及开发环境配置(vscodepython)

python安装 去Python官网下载最新版本&#xff1a; 接下来请一步步按照图片操作&#xff1a; 这样子就安装完成了 测试Python安装是否成功 先打开终端 右键Windows徽标&#xff0c;点击终端 然后输入python&#xff0c;如果如下图所示&#xff0c;就说明安装成功&#xff0…

【深度学习实战】利用Linear Regression预测房价

本文参考了李沐老师的b站深度学习课程 课程链接&#xff0c;使用了线性回归模型&#xff0c;特别适合深度学习初学者。通过阅读本文&#xff0c;你将学会如何用PyTorch训练模型&#xff0c;并掌握一些实用的训练技巧。希望这些内容能对你的深度学习学习有所帮助。 安装pytorch …

【书生大模型实战营(暑假场)】基础任务四 XTuner微调个人小助手认知

基础任务四 XTuner微调个人小助手认知 任务文档视频XTuner微调前置基础 文章目录 基础任务四 XTuner微调个人小助手认知0 认识微调0.1 Fine-tune 的两种范式0.2 常见微调技术 1 微调工具 XTuner1.1 认识高效微调框架 XTuner1.2 XTuner 具有出色的优化效果1.3 XTuner 零显存浪费…

【已成功EI检索】第五届新材料与清洁能源国际学术会议(ICAMCE 2024)

重要信息 会议官网&#xff1a;2024.icceam.com 接受/拒稿通知&#xff1a;投稿后1周内 收录检索&#xff1a;EI, Scopus 会议召开视频 见刊封面 EI检索页面 Scopus 检索页面 相关会议 第六届新材料与清洁能源国际学术会议&#xff08;ICAMCE 2025&#xff09; 大会官网&…

【Android】不同系统版本获取设备MAC地址

【Android】不同系统版本获取设备MAC地址 尝试实现 尝试 在开发过程中&#xff0c;想要获取MAC地址&#xff0c;最开始想到的就是WifiManager&#xff0c;但结果始终返回02:00:00:00:00:00&#xff0c;由于用得是wifi &#xff0c;考虑是不是因为用得网线的原因&#xff0c;但…

【海思SS626 | VB】关于 视频缓存池 的理解

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; &#x1f923;本文内容&#x1f923;&a…

【C#】explicit、implicit与operator

字面解释 explicit&#xff1a;清楚明白的;易于理解的;(说话)清晰的&#xff0c;明确的;直言的;坦率的;直截了当的;不隐晦的;不含糊的。 implicit&#xff1a;含蓄的;不直接言明的;成为一部分的;内含的;完全的;无疑问的。 operator&#xff1a;操作人员;技工;电话员;接线员;…

OSL 冠名赞助Web3峰会 “FORESIGHT2024”圆满收官

OSL 望为香港数字资产市场发展建设添砖加瓦 &#xff08;香港&#xff0c;2024 年 8 月 13 日&#xff09;- 8 月 11 日至 12 日&#xff0c; 由 香港唯一专注数字资产的上市公司 OSL 集团&#xff08;863.HK&#xff09;冠名赞助&#xff0c;Foresight News、 Foresight Ventu…

C++ 11相关新特性(lambda表达式与function包装器)

目录 lambda表达式 引入 lambda表达式介绍 lambda表达式捕捉列表的传递形式 lambda表达式的原理 包装器 包装器的基本使用 包装器与重载函数 包装器的使用 绑定 C 11 新特性 lambda表达式 引入 在C 98中&#xff0c;对于sort函数来说&#xff0c;如果需要根据不同的比较方式实现…

Springboot日志监听功能

目录 1. 概述1.1. 需求1.2. 思路 2. 功能实现2.1 依赖选取2.2 编写logBack.xml2.3 日志拦截2.4 封装请求为HttpServletRequestWrapper2.5 AOP2.6 日志监听 3. 后记 1. 概述 1.1. 需求 背景&#xff1a;拆分支付系统的日志&#xff0c;把每笔单子的日志单独拎出来存库。每笔单…

如何将高清图片修复?3个方法一键还原图片

如何将高清图片修复&#xff1f;高清图片修复是一个涉及图像处理技术的复杂过程&#xff0c;是对图片进行简单的调整或优化。这个过程旨在最大程度地恢复和提升图片的清晰度、细节和整体视觉效果&#xff0c;使其更加逼真、生动。通过高清图片的修复&#xff0c;我们可以让老旧…

稀疏注意力:时间序列预测的局部性和Transformer的存储瓶颈

时间序列预测是许多领域的重要问题&#xff0c;包括对太阳能发电厂发电量、电力消耗和交通拥堵情况的预测。在本文中&#xff0c;提出用Transformer来解决这类预测问题。虽然在我们的初步研究中对其性能印象深刻&#xff0c;但发现了它的两个主要缺点:(1)位置不可知性:规范Tran…

C++_2_ inline内联函数 宏函数(2/3)

C推出了inline关键字&#xff0c;其目的是为了替代C语言中的宏函数。 我们先来回顾宏函数&#xff1a; 宏函数 现有个需求&#xff1a;要求你写一个Add(x,y)的宏函数。 正确的写法有一种&#xff0c;错误的写法倒是五花八门&#xff0c;我们先来“见不贤而自省也。” // …

windows下部署redis3.2

一、下载redis3.2的包 6.2.6的包也有&#xff0c;但无法安装为Windows服务&#xff0c;暂时舍弃。 直接运行&#xff1a; redis-server redis.windows.conf 修改密码, 对应 redis.windows.conf 中的 requirepass 节点&#xff0c;注意去掉前面的# 修改端口&#xff0c;对应…

缺陷检测AI 重要参数解释

一、参数介绍 基本参数 True Positives (TP) True Positives (TP) 是一个用于评估模型性能的术语。它指的是模型正确预测为正例&#xff08;Positive&#xff09;的样本数量&#xff0c;即实际为正例且被正确分类为正例的样本数量。 False Positives (FP) FP (False Posit…

Python 文件目录操作,以及json.dump() 和 json.load()

import os 是用来引入 Python 标准库中的 os 模块的&#xff0c;这个模块提供了与操作系统交互的功能。这个模块常用于文件和目录操作&#xff0c;比如获取文件的目录路径、创建目录等。 如果你在代码中需要使用与操作系统相关的功能&#xff08;例如获取目录名、检查文件是否…