链表带环问题的思考

news2024/10/5 10:22:21

判断链表是否带环

思路:快慢指针

慢指针走一步,快指针走两步,当快指针追上慢指针时,代表该链表带环。代码如下:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
bool hasCycle(struct ListNode *head) {
    struct ListNode *fast = head, *slow = head;
    while(fast && fast->next)
    {
        slow = slow->next;
        fast = fast->next->next;
        if(slow == fast)
        {
            return true;
        }
        
    }
    return false;
}

拓展

1.为什么一定会相遇?

证明:

当slow进入环时,不妨设fast与slow的距离为N,每一次slow和fast前进时,它们之间的距离每次减一,N、N-1、N-2...2、1、0.故一定会相遇。

2.slow一次走一步,fast一次走3步,4步等等可以吗?

证明:

当fast一次走3步

同上,当slow进环后,slow与fast的距离每次减2,当N为偶数时,可以追上;当N为奇数时,它们之间的距离会减少到-1,进行下一轮追及。此时不妨设环长C,它们之间的距离变成C-1,进行下一轮追及。

如果C-1时奇数

即C是奇数,它们之间的距离又会达到-1,永远不会追上。

如果C-1是偶数

即C为偶数,它们可以追上。

如果fast走4步,5步.......

通过fast % 3 == 0,fast % 3 == 1.......判断。

思考:它们真的会永远追不上吗?

        前面我们证明了当C为偶数,N为奇数时,它们不会相遇,但C和N之间似乎也存在某种等量关系,这里我们对其进行证明:

        假设slow进环后移动的距离是L,假设此时fast已经移动了x圈,则fast总共移动的距离为:L + x * C + C - N。又因为fast移动的距离是slow的3倍,于是我们可以列出一个表达式:

3L == L + x * C + C - N.化简可得 2L == (X + 1)*C - N,2L一定是偶数,(x+1)*C一定是偶数,N是奇数,于是我们发现,这个等式不可能存在:因为偶数不可能等于偶数减奇数。

综上,N是奇数且C是偶数不能同时存在,故当fast走3步时,一定可以追上。

寻找带环链表的环入口

思路一:相遇节点

这里我们知道fast一次走两步,slow一次走一步时两指针一定会相遇,且一定是在slow移动的第一圈相遇,当slow指针移动到两指针相遇时,移动距离为:L + N。fast指针移动的距离为:L + N + x * C(x为fast已经移动的圈数)。联立得L = x * C - N。==》L = (x-1) * C + C - N此时相遇点的指针meet移动到入环节点的距离就是C-N == L。代码如下:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode *detectCycle(struct ListNode *head) {
    struct ListNode *fast = head, *slow = head;
    while(fast && fast->next)
    {
        slow = slow->next;
        fast = fast->next->next;

        if(slow == fast)
        {
            struct ListNode *meet = slow;
            while(meet != head)
            {
                meet = meet->next;
                head = head->next;
            }
            return meet;
        }
    }
    return NULL;
}

思路二:转换为链表相交

         我们可以将两指针相交节点的下一个节点设为meet,然后将相交节点指向空,目的是切断带环链表,将其转换为单链表,然后再通过判断链表相交函数实现返回链表带环的起始节点的目的。代码如下:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
    struct ListNode *pcur1 = headA, *pcur2 = headB;
    int len1 = 1, len2 = 1;
    while(pcur1)
    {
        pcur1 = pcur1->next;
        len1++; 
    }
    while(pcur2)
    {
        pcur2 = pcur2->next;
        len2++;
    }
    if(pcur1 != pcur2)
        return NULL;
    int gap = abs(len1 - len2);
    struct ListNode* LongList = headA, *ShortList = headB;
    if(len1 < len2)
    {
        LongList = headB;
        ShortList = headA;
    }
    while(gap--)
    {
        LongList = LongList->next;
    }
    while(LongList != ShortList)
    {
        LongList = LongList->next;
        ShortList = ShortList->next;
    }
    return LongList;
}

struct ListNode *detectCycle(struct ListNode *head) {
    struct ListNode *fast = head, *slow = head;
    while(fast && fast->next)
    {
        fast = fast->next->next;
        slow = slow->next;
        if(slow == fast)
        {
            struct ListNode *meet = slow->next;//找到相遇节点的下一个节点
            slow->next = NULL;//切断链表
            return getIntersectionNode(head, meet);
        }
    }
    return NULL;//若没有则返回空
}

综上,这道题,我们发现思路难,则代码简单;思路简单,则代码复杂。

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

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

相关文章

【服务器报错】Pycharm运行服务器代码提示 can‘t open file “本地文件路径“

1. 问题 Pycharm连接远程服务器&#xff0c;代码已经同步&#xff0c;运行时候报错 #模拟报错 bash: line 0: cd: G:/python/hhh/Hi: No such file or directory /home/hhh/anaconda3/envs/hard/bin/python: cant open file G:/python/hhh/hi/hei.py: [Errno 2] No such file…

Marvelous Designer12 解锁版安装教程 (3D服装设计软件)

前言 Marvelous Designer允许您使用我们的尖端设计软件创建美丽的3D虚拟服装。最后&#xff0c;使用工具在提高质量的同时节省时间&#xff0c;为您的设计注入活力。从基本衬衫到复杂的褶皱连衣裙和粗糙的制服&#xff0c;Marvelous Designer几乎可以将织物纹理和物理特性复制…

基于NAMUR开放式架构(NOA)的工业设备数据采集方案

一 NAMUR开放式架构 传统自动化金字塔结构的优越性在过去许多年里已被证明。然而&#xff0c;传统的自动化金字塔在获取和利用对物联网和工业4.0有价值的数据方面却存在一定挑战。这是因为传统系统通常是封闭的&#xff0c;数据访问受到限制&#xff0c;难以集成到新的数字化解…

GoldenEye-v1(vulnhub)靶机练习实践报告

GoldenEye-v1****靶机练习实践报告 一、安装靶机 靶机是.ova文件&#xff0c;需要用VirtualBox打开&#xff0c;但我习惯于使用VMWare,因此修改靶机文件&#xff0c;使其适用于VMWare打开。 解压ova文件&#xff0c;得到.ovf文件和.vmdk文件。 用记事本打开.ovf文件并修改“…

聚会活跃气氛神器小程序源码系统 各种小游戏 让聚会不再冷场 带源代码包以及安装搭建教程

系统概述 在社交聚会中&#xff0c;如何让气氛活跃起来一直是一个让人关注的问题。小编给大家分享一款聚会活跃气氛神器小程序源码系统。它不仅提供了丰富多样的小游戏&#xff0c;还带有源代码包和详细的安装搭建教程&#xff0c;让你轻松打造属于自己的聚会互动平台。 代码…

WPS文件没有保存怎么恢复?5个解决方案轻松恢复!

“我在WPS上编辑了一个文件&#xff0c;但是还没来得及将它保存&#xff0c;我不小心就退出软件了&#xff0c;现在不知道有什么方法可以恢复WPS文件呢&#xff1f;大家可以帮帮我吗” WPS作为一款功能强大且用户友好的软件&#xff0c;给我们的工作带来了很多的便利。但我们在…

谢宁DOE培训适合哪些人?

近年来&#xff0c;谢宁DOE培训以其专业、系统的课程内容&#xff0c;受到了众多学习者的青睐。那么&#xff0c;这个培训究竟适合哪些人呢&#xff1f;深圳天行健企业管理咨询公司解析如下&#xff1a; 首先&#xff0c;谢宁DOE培训适合质量管理部门的专业人员。质量总监、质量…

解线性方程组——最速下降法及图形化表示 | 北太天元 or matlab

一、思路转变 A为对称正定矩阵&#xff0c; A x b Ax b Axb 求解向量 x x x这个问题可以转化为一个求 f ( x ) f(x) f(x)极小值点的问题&#xff0c;为什么可以这样&#xff1a; f ( x ) 1 2 x T A x − x T b c f(x) \frac{1}{2}x^TAx - x^Tb c f(x)21​xTAx−xTbc 可…

书籍学习|基于SprinBoot+vue的书籍学习平台(源码+数据库+文档)

书籍学习平台 目录 基于SprinBootvue的书籍学习平台 一、前言 二、系统设计 三、系统功能设计 1平台功能模块 2后台功能模块 5.2.1管理员功能模块 5.2.2用户功能模块 5.2.3作者功能模块 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 …

MyBatis的基础操作

目录 一.什么是MyBatis? 二.使用MyBatis的准备工作 1.引入依赖: 2.配置数据库连接字符串(建立MaBatis和MySQL的连接) 3.在model包中建立数据库对应的实体类UserInfo 三.通过注解的方式实现MyBatis的开发 1.插入语句(Insert) 2.删除语句(Delete) 3.更新语句(Update) 4…

好用的便签如何独立和组合便签窗口

便签&#xff0c;那些小小的纸片&#xff0c;曾经是我生活中的忠实记录者。每当灵感闪现&#xff0c;或是有什么待办事项&#xff0c;我都会随手写在便签上&#xff0c;然后贴在我目所能及的地方&#xff0c;以便随时提醒我。然而&#xff0c;纸质便签总有其局限性&#xff0c;…

springboot个人旅游管理系统设计与实现-计算机毕业设计源码75806

摘要 在社会快速发展和人们生活水平提高的影响下&#xff0c;旅游产业蓬勃发展&#xff0c;旅游形式也变得多样化&#xff0c;使个人旅游的管理变得比过去更加困难。依照这一现实为基础&#xff0c;设计一个快捷而又方便的基于小程序的个人旅游管理系统是一项十分重要并且有价值…

4个月赚20万!一张图赚7500!多种变现方式,一个被忽视的暴力项目

大家好&#xff0c;今天给大家带来一个被很多人忽视&#xff0c;不起眼确很暴力的项目。 大胆放心干 课程获取&#xff1a; https://hsgww.com/https://hsgww.com/

(二刷)代码随想录第15天|层序遍历 226.翻转二叉树 101.对称二叉树2

层序遍历 10 102. 二叉树的层序遍历 - 力扣&#xff08;LeetCode&#xff09; 代码随想录 (programmercarl.com) 综合代码&#xff1a; class Solution{public List<List<Integer>> resList new ArrayList<List<Integer>>();public List<List<…

ComfyUI 简化工作流神器

安装也很简单&#xff0c;只需要在 ComfyUI 管理器中搜索「efficiency-nodes-comfyui」&#xff0c;点击安装就可以了。 插件也会放到文末的网盘中&#xff0c;有需要的小伙伴自取&#xff0c;复制到插件目录「\ComfyUI\custom_nodes」下就可以了。安装好了&#xff0c;记得重…

立创·天空星开发板-GD32F407VE-环境搭建

本文以 立创天空星开发板-GD32F407VET6-青春版 作为学习的板子&#xff0c;记录学习笔记。 立创天空星开发板-GD32F407VET6-环境搭建 单片机ARMARM内核系列Cortex-M系列常用ARM芯片厂商 GD32GD32的产品系列开发板开发板资源、尺寸标注图设计图纸 GD32F407 Keil ARM 安装下载地址…

视频营销的智能剪辑:Kompas.ai如何塑造影响力视频内容

引言&#xff1a; 在当今数字化的营销领域&#xff0c;视频内容已经成为品牌吸引用户注意力、建立品牌形象和提升用户参与度的重要方式。然而&#xff0c;要想制作出具有影响力的视频内容&#xff0c;并不是一件容易的事情。这就需要借助先进的技术和工具&#xff0c;如人工智能…

【Java面试】四、MySQL篇(上)

文章目录 1、定位慢查询2、慢查询的原因分析3、索引3.1 数据结构选用&#xff1a;二叉树 & 红黑树3.2 数据结构选用&#xff1a;B树 4、聚簇索引、非聚簇索引、回表查询4.1 聚簇索引、非聚簇索引4.2 回表查询 5、覆盖索引、超大分页优化5.1 覆盖索引5.2 超大分页处理 6、索…

前端JS必用工具【js-tool-big-box】学习,获取数据的详细类型

之前我们习惯性的用typeof方法去判断数据类型&#xff0c;但慢慢的发现&#xff0c;typeof这个方法能力有限&#xff0c;基础的数据类型倒是还能判断&#xff0c;但是复杂一点&#xff0c;或者是null之类的假类型&#xff0c;就判断不出来了。 比如以下这些判断&#xff1a; …

【软件设计师】——5.数据库系统

目录 5.1 基本概念 5.2 三级模式两级映射 5.3 设计过程和数据模型 5.4 关系代数 5.5 完整性约束 5.6 规范化和反规范化 5.7 控制功能 5.8 SQL语言 5.9 数据库安全 5.10 数据备份 5.11 数据库故障与恢复 5.12 数据仓库、数据挖掘和大数据 5.1 基本概念 相关术语 候选…