LeetCode 141题:环形链表的艺术与科学

LeetCode 141题:环形链表的艺术与科学

🌟 LeetCode 141题:环形链表的艺术与科学

因为想更好地为义父义母大佬服务,本文 Bilibili 视频地址

🌀 环形链表:当数据开始循环舞蹈

在计算机科学的世界里,链表是一种优雅而基础的数据结构。正常链表如同一条笔直的小路,从起点(head)出发,每个节点指向下一个节点,最终以空指针(nullptr)作为终点,标志着旅程的结束。

Head

Node1

Node2

Node3

nullptr

然而,环形链表则打破了这种线性规则,它更像是一个神秘的莫比乌斯环,没有真正的终点。链表的某个节点不再指向空,而是指向链表中已经存在的另一个节点,形成了一个无尽的循环。

Head

Node1

Node2

Node3

Node4

🔍 解法一:哈希表法 - 记忆的艺术

解题思路

想象你是一位侦探,正在追踪一个可能陷入循环的线索。你需要记录下每一个经过的节点,就像在犯罪地图上钉上标记。每当遇到新节点时,你都要检查这个地点是否曾经出现过。

boolhasCycle(ListNode *head){ unordered_set<ListNode*> visited;while(head !=nullptr){if(visited.count(head)){returntrue;// 发现重复访问,存在环} visited.insert(head); head = head->next;}returnfalse;// 正常到达终点,无环}

性能分析

指标说明
时间复杂度O(n)最坏情况需要遍历整个链表
空间复杂度O(n)需要存储所有访问过的节点

这种方法直观易懂,但需要额外的存储空间。哈希表的选择至关重要,它决定了查找效率。在C++中,unordered_set提供了平均O(1)的查找时间复杂度。

🏃‍♂️ 解法二:快慢指针法 - 龟兔赛跑的智慧

解题思路

受龟兔赛跑寓言的启发,我们让两个指针以不同速度遍历链表。如果存在环,快指针终将追上慢指针;如果不存在环,快指针会先到达终点。

指针移动

Head

Node1

Node2

Node3

Node4

slow

fast

boolhasCycle(ListNode *head){if(head ==nullptr|| head->next ==nullptr){returnfalse;} ListNode* slow = head; ListNode* fast = head->next;while(slow != fast){if(fast ==nullptr|| fast->next ==nullptr){returnfalse;// 快指针到达终点,无环} slow = slow->next;// 乌龟每次一步 fast = fast->next->next;// 兔子每次两步}returntrue;// 相遇,存在环}

性能优势

指标说明
时间复杂度O(n)线性时间解决问题
空间复杂度O(1)仅需两个指针,常数空间

这种方法不需要额外存储空间,是空间最优解。它体现了计算机科学中常见的双指针技巧,广泛应用于链表相关问题。

💻 代码实现与调试心得

在力扣平台上实现时,有几个关键点需要注意:

  1. 边界条件处理:空链表或单节点链表直接返回false
  2. 指针移动顺序:先移动指针再判断,避免错过相遇点
  3. 循环终止条件:快指针或其next为null时即可确定无环

调试过程中,我最初忽略了fast->next的判空,导致在偶数长度链表上报错。通过添加这个检查,代码变得更加健壮。

🌈 思维与实现的分离

在解决算法问题时,思维过程具体实现是两个不同的层面:

  1. 思维层面:考虑问题本质,寻找规律和模式
  2. 实现层面:将思维转化为代码,处理边界条件和语言特性

优秀的程序员能够在这两个层面间自如切换,既能看到森林,也能处理每棵树。

🎯 总结

环形链表判断是链表操作中的经典问题,两种解法各有千秋:

  • 哈希表法:直观易懂,适合教学和理解问题本质
  • 快慢指针法:空间高效,体现了算法优化的智慧
 LeetCode 141题:环形链表的艺术与科学

掌握这两种方法,不仅能解决LeetCode 141题,更能为处理更复杂的链表问题打下坚实基础。记住,在编程的世界里,有时候跑得快的兔子确实能教会我们很多!

Read more

Flutter 组件 simplify 的适配 鸿蒙Harmony 实战 - 驾驭路径精简算法、实现鸿蒙端高性能地理足迹渲染与矢量图形优化方案

Flutter 组件 simplify 的适配 鸿蒙Harmony 实战 - 驾驭路径精简算法、实现鸿蒙端高性能地理足迹渲染与矢量图形优化方案

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 组件 simplify 的适配 鸿蒙Harmony 实战 - 驾驭路径精简算法、实现鸿蒙端高性能地理足迹渲染与矢量图形优化方案 前言 在鸿蒙(OpenHarmony)生态的运动健康轨迹展示、高精度室内导航以及大规模矢量地图看板开发中,“路径性能”是决定用户滑动流畅度的核心红线。面对用户运动 1 小时产生的包含数万个(X, Y)坐标点的原始 GPS 序列。如果直接将其交给鸿蒙端的渲染层进行绘制,不仅会引发由于顶点(Vertices)过多导致的 GPU 负载饱和。更会由于频繁的坐标点内存申请(Memory Allocation),产生严重的 UI 掉帧与功耗飙升。 我们需要一种“去重存精、视觉无损”的几何精简艺术。 simplify 是一套专注于极致性能的 Douglas-Peucker 及其增强算法实现。它能瞬间将冗余的、

By Ne0inhk
【优选算法】双指针算法:专题一

【优选算法】双指针算法:专题一

目录 引言: 【283.移动零】 1、题目描述 2、实现核心及思路 解题思路: 思路可视化: 代码实现: 代码测试: 【1089.复写零】 1、题目描述 2、实现核心及思路 解题思路: 思路可视化: 代码实现: 代码测试: 【202. 快乐数】 1、题目描述 2、实现核心及思路 解题思路: 代码实现: 【11. 盛水最多容器】 1、题目描述 2、实现核心及思路 解题思路: 思路可视化: 代码实现: 引言: 常见的双指针有两种形式,一种是对撞指针,一种是快慢指针。 对撞指针:一般用于顺序结构中,也称左右指针。 • 对撞指针从两端向中间移动。一个指针从最左端开始,另一个从最右端开始,然后逐渐往中间逼近。

By Ne0inhk
算法入门:专题攻克一---双指针4(三数之和,四数之和)强推好题,极其锻炼算法思维

算法入门:专题攻克一---双指针4(三数之和,四数之和)强推好题,极其锻炼算法思维

🎬 胖咕噜的稞达鸭:个人主页 🔥 个人专栏: 《数据结构》《C++初阶高阶》《算法入门》 ⛺️技术的杠杆,撬动整个世界! 三数之和 三数之和 1. 题目分析: 取三元组中的三个数,num[i], num[j], num[k], i!=j, i != k; j != k ,也就是说一次取到的三个数不可以是相同位置的,三个数的位置各不相同。同时也满足三个数的相加等于0。最后还得是不同的组合(去重操作)。 这里给一个数组,便于演示: 【 -4 -4 -1 0 0 0 1 1 4 4 5 6】 2. 算法原理: 解法一:先排序+暴力枚举+

By Ne0inhk
《算法闯关指南:动态规划算法--斐波拉契数列模型》--01.第N个泰波拉契数,02.三步问题

《算法闯关指南:动态规划算法--斐波拉契数列模型》--01.第N个泰波拉契数,02.三步问题

🔥草莓熊Lotso:个人主页 ❄️个人专栏: 《C++知识分享》《Linux 入门到实践:零基础也能懂》 ✨生活是默默的坚持,毅力是永久的享受! 🎬 博主简介: 文章目录 * 前言: * 01.第N个泰波拉契数 * 解法(动态规划): * 算法流程: * C++算法代码: * 算法总结&&笔记展示: * 02.三步问题 * 解法(动态规划): * 算法思路: * C++算法代码: * 算法总结&&笔记展示: * 结尾: 前言: 聚焦算法题实战,系统讲解三大核心板块:优选算法:剖析动态规划、二分法等高效策略,学会寻找“最优解”。 递归与回溯:掌握问题分解与状态回退,攻克组合、排列等难题。 贪心算法:理解“

By Ne0inhk