Swift 实现查找链表入环点:快慢指针法

在这里插入图片描述
在这里插入图片描述

文章目录

    • 前言
    • 摘要
    • 描述
    • 题解答案
    • 题解代码
    • 题解代码分析
    • 示例测试及结果
    • 时间复杂度
    • 空间复杂度
    • 总结

前言

本题由于没有合适答案为以往遗留问题,最近有时间将以往遗留问题一一完善。

142. 环形链表 II

不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。

难度水平:中等

摘要

链表问题中,查找环的起始节点是一个经典的进阶题目。本篇文章将讲解如何在 Swift 中实现 查找链表入环点 的算法,并通过 快慢指针法 实现 O(1) 空间复杂度,详细分析代码逻辑并给出完整的测试案例。

描述

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

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

不允许修改 链表。

示例 1:
在这里插入图片描述

输入: head = [3,2,0,-4], pos = 1
输出: 返回索引为 1 的链表节点
解释: 链表中有一个环,其尾部连接到第二个节点。

示例 2:

在这里插入图片描述

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

示例 3:

在这里插入图片描述

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

提示:

  • 链表中节点的数目范围在范围 [0, 104]
  • -105 <= Node.val <= 105
  • pos 的值为 -1 或者链表中的一个有效索引

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

题解答案

我们采用 快慢指针法 解决该问题。
在之前判断链表是否存在环的基础上,进一步确定环的起始节点。

核心思路:

  1. 使用快慢指针判断链表是否有环。
  2. 若有环,快慢指针相遇时,将其中一个指针重新指向链表头节点,并保持另一个指针在相遇点。
  3. 两个指针以相同的速度前进,相遇时的节点即为入环点。

题解代码

以下是 Swift 实现代码:

// 定义链表节点
class ListNode {var val: Intvar next: ListNode?init(_ val: Int) {self.val = valself.next = nil}
}func detectCycle(_ head: ListNode?) -> ListNode? {var slow = headvar fast = head// 快慢指针判断是否有环while let nextFast = fast?.next {slow = slow?.nextfast = nextFast.nextif slow === fast {// 有环,查找环的起点var pointer1 = headvar pointer2 = slowwhile pointer1 !== pointer2 {pointer1 = pointer1?.nextpointer2 = pointer2?.next}return pointer1}}// 无环return nil
}

题解代码分析

  1. 快慢指针的初始化

    • 慢指针每次走一步,快指针每次走两步。
    • 快指针达到链表末尾时(fast == nilfast.next == nil),说明链表无环。
  2. 检测环的存在

    • 若快慢指针在某个节点相遇,则链表中存在环。
    • 慢指针和快指针的路径会在环中循环,从而必定相遇。
  3. 确定环的起始节点

    • 相遇后,将其中一个指针(如 pointer1)重新指向链表头节点,另一个指针(如 pointer2)保持在相遇点。
    • 两个指针每次走一步,最终相遇时的节点即为环的起始节点。
  4. 时间复杂度

    • 检测环的阶段:O(n),链表节点最多被访问两次。
    • 找入环点的阶段:O(n),快慢指针最多走一圈。
    • 总时间复杂度:O(n)
  5. 空间复杂度

    • 只使用了两个指针,空间复杂度为 O(1)

示例测试及结果

以下是测试代码:

// 创建测试用例
func createLinkedListWithCycle(_ values: [Int], _ pos: Int) -> ListNode? {guard !values.isEmpty else { return nil }let head = ListNode(values[0])var current = headvar cycleNode: ListNode? = nilfor i in 1..<values.count {let node = ListNode(values[i])current.next = nodecurrent = nodeif i == pos {cycleNode = node}}// 创建环if let cycleNode = cycleNode {current.next = cycleNode}return head
}// 示例 1
let head1 = createLinkedListWithCycle([3, 2, 0, -4], 1)
print(detectCycle(head1)?.val ?? "No cycle") // 输出: 2// 示例 2
let head2 = createLinkedListWithCycle([1, 2], 0)
print(detectCycle(head2)?.val ?? "No cycle") // 输出: 1// 示例 3
let head3 = createLinkedListWithCycle([1], -1)
print(detectCycle(head3)?.val ?? "No cycle") // 输出: No cycle

测试结果:

2
1
No cycle

时间复杂度

  • 检测环的复杂度:每个节点最多访问两次,复杂度为 O(n)
  • 找入环点的复杂度:环内最多走一圈,复杂度为 O(n)
  • 总复杂度O(n)

空间复杂度

  • 仅使用两个指针变量,额外空间为常量 O(1)

总结

本题通过 快慢指针法 高效解决了链表入环点的查找问题。在实际开发中,这种方法不仅可以用于链表问题,还可扩展到许多类似的循环检测场景。

关键点总结:

  • 快慢指针的技巧。
  • 环形结构的性质。
  • 利用数学和逻辑简化复杂问题。

本篇文章中提供的代码实现和详细解释,希望能帮助您掌握链表环问题的核心解法。如果有疑问或更好的优化建议,欢迎讨论!

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

stable-diffusion-webui在conda pycharm中运行

目录 简介下载conda环境配置环境变量修改launch_utils.py文件运行stable-diffusion-webui下载模型文本生成图片参考 简介 stable-diffusion-webui是AI绘画 Stable Diffusion浏览器UI界面&#xff0c;为用户提供了一个简单、直观的方式来利用 Stable Diffusion 技术创建视觉内容…

小柴冲刺软考中级嵌入式系统设计师系列二、嵌入式系统硬件基础知识(7)嵌入式Soc

越努力&#xff0c;越幸运&#xff01; 分享一个晚霞&#xff0c;真的好美啊&#x1f496;&#xff01; 添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09; 不得不说&#xff0c;我还是喜欢在人少的地方生活啊。 flechazohttps://www.zhihu.com/people/ji…

【云计算网络安全】解析 Amazon 安全服务:构建纵深防御设计最佳实践

文章目录 一、前言二、什么是“纵深安全防御”&#xff1f;三、为什么有必要采用纵深安全防御策略&#xff1f;四、以亚马逊云科技为案例了解纵深安全防御策略设计4.1 原始设计缺少安全策略4.2 外界围栏构建安全边界4.3 访问层安全设计4.4 实例层安全设计4.5 数据层安全设计4.6…

产业用机器人中的旋转花键若损伤有何影响?

旋转花键在产业用机器人中是关键的组件之一&#xff0c;如果机器人中的旋转花键损坏&#xff0c;会对机器人的运行和性能产生一定影响。以下是可能的影响&#xff1a; 1、功能受限&#xff1a;旋转花键用于连接两个旋转部件&#xff08;例如电机轴和传动轴&#xff09;&#xf…

基于STM32的火灾报警装置的Proteus仿真

文章目录 一、火灾报警1.题目要求2.思路2.1 主控2.2 传感器2.3 设定阈值--按键2.4 报警和通风2.5 OLED显示2.6 电源部分2.7 远程终端 3.仿真3.1 未仿真时3.2 仿真开始&#xff0c;界面13.3 切换界面23.4 切换界面3 4.仿真程序4.1 程序说明4.2 主函数4.3 OLED显示函数 二、总结 …

人脸检测开源项目介绍【持续更新】

DeepFace 介绍&#xff1a;DeepFace是一个轻量级的人脸识别和面部属性分析框架&#xff0c;专为Python设计。它集成了多种前沿的深度学习模型&#xff0c;包括VGG-Face、FaceNet、OpenFace、DeepFace、DeepID、ArcFace、Dlib、SFace和GhostFaceNet等&#xff0c;能够进行年龄、…

RabbitMQ 之 死信队列

一、死信的概念 先从概念解释上搞清楚这个定义&#xff0c;死信&#xff0c;顾名思义就是无法被消费的消息&#xff0c;字面意思可以这样理 解&#xff0c;一般来说&#xff0c;producer 将消息投递到 broker 或者直接到 queue 里了&#xff0c;consumer 从 queue 取出消息进行…

使用 LSTM(长短期记忆网络) 模型对时间序列数据(航空旅客人数数据集)进行预测

代码功能 数据准备 加载数据&#xff1a;从公开的航空旅客人数数据集&#xff08;Airline Passengers Dataset&#xff09;中读取时间序列数据。 对数变换和平稳化&#xff1a;对数据应用 log1p 函数减少趋势和波动&#xff0c;使模型更容易学习规律。 归一化处理&#xff1a;…

《操作系统 - 清华大学》5 -2:覆盖技术

文章目录 1. 目标2. 覆盖的基本原理3. 覆盖技术的不足 1. 目标 覆盖技术产生于上世纪80年代和90年代初的时候&#xff0c;在那时候操作系统能力是很弱的&#xff0c;所以说当初目标是要在能够比较小的可用内存中运行比较大的程序&#xff0c;这个比较小&#xff0c;比较大的相对…

使用 Nginx 在 Ubuntu 22.04 上安装 LibreNMS 开源网络监控系统

#LibreNMS 是一个功能强大的开源网络监控系统&#xff0c;它能够为你的网络性能和设备提供全面的监控。本文将引导你通过一系列步骤&#xff0c;在 Ubuntu 22.04 服务器上安装和配置 LibreNMS&#xff0c;使用 Nginx 作为 Web 服务器。 简介 LibreNMS 提供了对网络设备和性能…

Spring注入Map学习

Spring注入Map学习 在Spring中 在策略模式中, 会经常用到 根据Bean名称获取Bean的实例 有2个方法很好用 1. 使用Autowired注入 2. 使用构造方法注入 但是奇怪的一点是: 日志打印并没有看到结果, 第一行的 Autowired的结果 是个null 那是因为 注入时机 的问题 注入时机&…

【Redis_Day5】String类型

【Redis_Day5】String类型 String操作String的命令set和get&#xff1a;设置、获取键值对mset和mget&#xff1a;批量设置、获取键值对setnx/setex/psetexincr和incrby&#xff1a;对字符串进行加操作decr/decrby&#xff1a;对字符串进行减操作incrbyfloat&#xff1a;浮点数加…

谷歌云无法ssh登录(修改sshd_config也不行)

sudo -i vi /etc/ssh/sshd_config passwd root /etc/init.d/ssh restart service sshd restart 这是网站大部分教程讲的&#xff0c;但是我实际试了还是连不上 参考https://linux.do/t/topic/260732/15 原来/etc/ssh/sshd_config.d/下面有个60开头的文件&#xff0c;也需…

【FPGA-MicroBlaze】串口收发以及相关函数讲解

前言 工具&#xff1a;Vivado2018.3及其所对应的SDK版本 目前网上有许多MicroBlaze 的入门教程&#xff0c;比如下面的这个参考文章&#xff0c;用串口打印一个hello world。 【FPGA】Xilinx MicroBlaze软核使用第一节&#xff1a;Hello World!_fpga软核microblaze-CSDN博客 个…

【君正T31开发记录】8.了解rtsp协议及设计模式

前边搞定了驱动&#xff0c;先不着急直接上手撸应用层的代码&#xff0c;先了解一下大致要用到的东西。 设计PC端先用vlc rtsp暂时H264编码&#xff08;vlc好像不支持h265,这个后边我试试&#xff09;的视频流&#xff0c;先需要支持上rtsp server&#xff0c;了解rtsp协议是必…

渗透测试---shell(7)for循环2与while循环

声明&#xff1a;学习素材来自b站up【泷羽Sec】&#xff0c;侵删&#xff0c;若阅读过程中有相关方面的不足&#xff0c;还请指正&#xff0c;本文只做相关技术分享,切莫从事违法等相关行为&#xff0c;本人与泷羽sec团队一律不承担一切后果 视频地址&#xff1a;泷羽--shell&a…

CLIP-Adapter: Better Vision-Language Models with Feature Adapters 论文解读

abstract 大规模对比视觉-语言预训练在视觉表示学习方面取得了显著进展。与传统的通过固定一组离散标签训练的视觉系统不同&#xff0c;(Radford et al., 2021) 引入了一种新范式&#xff0c;该范式在开放词汇环境中直接学习将图像与原始文本对齐。在下游任务中&#xff0c;通…

C++初阶(十五)--STL--list 的深度解析与全面应用

文章目录 一、头文件与基本概念 二、构造函数和析构函数 1.构造函数 2.析构函数 三、元素访问 front back 四、迭代器相关函数 begin end rebegin&#xff08;反向迭代器&#xff09; rend&#xff08;反向迭代器&#xff09; 五、容量相关函数 empty size max…

一个关于 CSS Modules 的陷阱

我在引用 less 文件样式的时候&#xff0c;发现 index.less .drag_upload {width: 100%;height: 90vh;padding: 20px; }index.jsx import React, { useState, useEffect } from react; import styles from ./index.less;export default ({ }) > {return (<div classNa…

基于STM32的智能家居电器控制系统

目录 引言环境准备 2.1 硬件准备 2.2 软件准备智能家居电器控制系统基础 3.1 控制系统架构 3.2 功能描述代码实现&#xff1a;实现智能家居电器控制系统 4.1 数据采集模块 4.2 控制逻辑与设备管理 4.3 通信与远程控制实现 4.4 用户界面与数据可视化应用场景&#xff1a;家庭自…