【数据结构OJ题】链表带环问题

news2024/12/23 10:16:49

目录

1.判断链表是否带环

证明

2.寻找环的入口点


1.判断链表是否带环

原题链接:力扣

思路一:先遍历一遍链表,计算出链表的长度,然后将长度除二,在遍历半个链表即可。但是这种方法效率比较低。

思路二:使用快慢指针,慢指针每次走1步,快指针每次走2步,当快指针走到末尾是,慢指针的位置就是链表中间位置。

下面我们使用思路二来完成题目:

bool hasCycle(struct ListNode* head) 
{
    struct ListNode* slow = head;
    struct ListNode* fast = head;
    while (fast && fast->next)
    {
        slow = slow->next;
        fast = fast->next->next;
        if (fast == slow)
        {
            return true;
        }
    }
    return false;
}

证明

1.为什么快指针每次走两步,慢指针走一步可以追上?

2.快指针一次走3步,走4步,...n步行吗?

证明:假设slow进环以后,fast和slow的距离是N

这时fast真正开始追击slow,fast一次走2步,slow一次走1步,他们之间的距离每次缩小1

假设slow进环以后,fast和slow的距离是N

这时fast真正开始追击slow,fast一次走3步,slow一次走1步,他们之间的距离每次缩小2

这时候要分情况讨论:

 

2.寻找环的入口点

原题链接:力扣

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

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

不允许修改链表。

方法一:用一个指针从链表的头节点出发,另一个指针从链表相遇的节点出发,当这两个指针相遇时,说明它们到达了入口

下面是原理:

 代码实现:

struct ListNode *detectCycle(struct ListNode *head) 
{
    struct ListNode* slow = head;
    struct ListNode* fast = head;
    while (fast && fast->next)
    {
        slow = slow->next;
        fast = fast->next->next;
        if (fast == slow)
        {
           struct ListNode *meet=slow;
           while(meet!=head)
           {
               meet=meet->next;
               head=head->next;
           }
           return meet;
        }
    }
    //如果链表没有环就返回空
    return NULL;
}

方法二:可以将这个题转化成两个链表相交的问题。

将meet的下一个节点设置成newHead,求出head到meet的长度n, newHead到meet的长度m, 再利用快慢指针,使长的链表先走fabs(m-n)次,再同时走,当两个指针想等时,就到达了环的入口。

 代码实现:

struct ListNode* detectCycle(struct ListNode* head)
{
    struct ListNode* slow = head;
    struct ListNode* fast = head;
    while (fast && fast->next)
    {
        slow = slow->next;
        fast = fast->next->next;
        if (slow == fast)
        {
            struct ListNode* meet = slow;
            struct ListNode* moveA = slow;
            struct ListNode* moveB = head;

            //计算两链表的长度
            int lenA = 0;
            int lenB = 0;
            while (moveA != meet)
            {
                moveA = moveA->next;
                lenA++;
            }
            while (moveB != slow )
            {
                moveB = moveB->next;
                lenB++;
            }

            //计算长度差
            int gab = fabs(lenA - lenB);
            
            struct ListNode* longList = head;
            struct ListNode* shortList = slow;
            if (lenA < lenB)
            {
                longList = slow;
                shortList = head;
            }
            //让长的链表先走
            while (gab--)
            {
                longList = longList->next;
            }

            while (longList != shortList)
            {
                longList = longList->next;
                shortList = shortList->next;
            }
            return longList;
        }
    }

    //不相交返回空
    return NULL;
}

很明显的看出来,使用方法二的代码比方法一要复杂的多

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

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

相关文章

【软考网络管理员】2023年软考网管初级常见知识考点(30)-文件管理与传送控制

涉及知识点 文件管理的概念&#xff0c;绝对路径和相对路径&#xff0c;设备管理&#xff0c;IO控制方式有哪些。 软考网络管理员常考知识点&#xff0c;软考网络管理员网络安全&#xff0c;网络管理员考点汇总。 原创于&#xff1a;CSDN博主-《拄杖盲学轻声码》&#xff0c;更…

天天做Web测试,咋还不知道怎么测试呢?

目录 前言&#xff1a; 一、UI测试 二、链接测试 三、搜索测试 四、表单提交测试 五、输入域测试 六、分页测试 七、兼容性测试 前言&#xff1a; Web测试是一个比较广泛的测试领域&#xff0c;涵盖的测试内容较多&#xff0c;包括功能测试、性能测试、安全测试等。 下面就说一…

Docker 新手向导

博文目录 文章目录 新手向导 (Get Started)应用程序容器化下载应用代码容器化该应用配置镜像加速器 启动这个应用容器 更新应用程序共享应用程序推送镜像Play with Docker使用镜像 持久化数据库容器的文件系统容器卷 (Container volumes)保留所有数据深入卷 使用绑定装载快速卷…

Android Jetpack Compose之TabRow的使用

Android Jetpack Compose是一个现代化的UI工具包&#xff0c;它让开发者可以以声明式的方式来构建出美观且功能强大的Android应用。在本文中&#xff0c;我们将详细介绍其中的一个重要组件——TabRow。 一. TabRow简介 TabRow是Jetpack Compose中的一个组件&#xff0c;主要用…

在家用电脑怎么赚钱,在家就能获得收益的三种方式

如何在家赚钱可能是许多人都困扰的问题之一。实际上&#xff0c;有很多在家赚钱的方法可供选择。然而&#xff0c;我在网上发现许多人缺乏学习的动力&#xff0c;不愿意承担风险&#xff0c;因此大约80%的人选择从事辛苦劳动或成为被剥削的人&#xff0c;导致他们连续几年在互联…

SpringBoot中的bean管理

一、获取bean 默认情况下&#xff0c;Spring项目启动时&#xff0c;会把bean都创建好放在IOC容器中&#xff0c;如果想要主动获取这些bean&#xff0c;可以通过如下方式: 根据name获取bean: object getBean (String name)根据类型获取bean: <T> T getBean (Class<…

8.1 PowerBI系列之DAX函数专题-进阶-解决列排序对计算的影响

需求 下列矩阵中&#xff0c;在月份列不按照原始数据的month_no排列时&#xff0c;能正确计算销售额占比&#xff0c;但是当月份按照month_no排序时就会出错&#xff0c;需要解决这个问题。 实现 month % divide([amount],calculate([amount],all(date[month desc]))) //排…

计算机网络—局域网

文章目录 ARP协议以太网以太网帧结构交换机交换机的端口划分 PPP协议 MAC地址 封装在链路帧中的地址&#xff0c;作为每一个接口的地址。&#xff08;一般是48bit大小&#xff09; MAC地址是刻画到我们物理接口上的&#xff0c;我们的网卡一旦出厂之后就会携带一个唯一的物理地…

升级HarmonyOS 3,通话一步切换更便捷

小伙伴们&#xff0c;今天和大家来聊聊HarmonyOS 3音频播控中心有哪些真香体验。不少朋友可能会脱口而出&#xff1a;一键切换音频App&#xff0c;一键实现音频跨设备流转&#xff0c;还有音频共享。这一次&#xff0c;音频播控中心又带来了新技能——一键切换通话音频。 相信大…

Java集合相关问题

java集合框架体系 数据结构 算法复杂度分析 时间复杂度分析&#xff1a;对代码运行时间所消耗时间多少进行分析空间复杂度分析&#xff1a;对代码运行所占用的内存的大小进行分析 时间复杂度 时间复杂度分析&#xff1a;来评估代码的执行耗时 假如执行每行代码的执行耗时一…

electron实现子窗口中创建右键菜单

后续可能会用electron开发一些工具&#xff0c;包括不限于快速生成个人小程序、开发辅助学习的交互式软件、帮助运维同学一键部署的简易版CICD工具等等。 开发进度&#xff0c;取决于我懒惰的程度。 不过不嫌弃的同学还是可以先关注一波小程序&#xff0c;真的发布工具了&…

Shopee(虾皮)运营没流量?没销量?只因你没掌握店铺引流方法大全

一、站内引流 - 类目 选品&#xff1a;侧重高性价比的潮流商品&#xff0c;及时上架销售热卖商品&#xff1b; 根据目标客户群选品&#xff1a;比如&#xff0c;如果60%-70%的用户为年轻女性&#xff0c;则关注性价比高的潮流商品&#xff1b; 根据重点品类选品&#xff1a;流…

C语言笔记-小智课堂-常用语法

嵌入式常用C语言语法 - 小智课程 类型&字节转换 define语法 define只是单纯替换&#xff0c;如果是运算记得加括号 防止多个文件调用重定义问题 define与typedef&#xff08;替换与别名&#xff09; enum语法 enum用于变量的枚举。 定义枚举类型的变量&#xff0c;变量…

MSP430G2553 Proteus仿真0~5V电压表数码管显示报警系统-0046

MSP430G2553 Proteus仿真0~5V电压表数码管显示报警系统-0046 Proteus仿真小实验&#xff1a; MSP430G2553 Proteus仿真0~5V电压表数码管显示报警系统-0046 功能&#xff1a; 硬件组成&#xff1a;51单片机 8位数码管MAX7219数码管驱动模块多个按键LED灯蜂鸣器 1.准确测量信…

43 # buffer 的应用

buffer Buffer 代表的都是二进制数据&#xff0c;代表是内存&#xff0c;它不能扩容&#xff08;java 数组不能扩容&#xff0c;想扩容可以使用动态数组&#xff0c;或者生成一个新的内存拷贝过去&#xff09; 服务端可以操作二进制&#xff0c;Buffer 可以和字符串进行相互转…

学习adaboost(二,第一次迭代,c#实现)

我觉得这两个公式推导的特别好。我们来搞第一次迭代&#xff1a; 我们取x<2.5,标签1&#xff0c;else&#xff0c;标签-1这个分类器&#xff0c;发现分错的是5&#xff0c;7&#xff0c;8三组数据 &#xff0c;正确的都由0.1变为0.0714了&#xff0c;降低了&#xff0c;错误…

课程20:API项目重构

🚀前言 本文是《.Net Core从零学习搭建权限管理系统》教程专栏的课程(点击链接,跳转到专栏主页,欢迎订阅,持续更新…) 专栏介绍:以实战为线索,基于.Net 7 + REST + Vue、前后端分离,不依赖任何第三方框架,从零一步一步讲解权限管理系统搭建。 专栏适用于人群:We…

Debezium系列之:记录一次Debezium集群服务器端口打满的原因和对应的解决方法

Debezium系列之:记录一次Debezium集群服务器端口打满的原因和对应的解决方法 一、背景二、查看被占端口使用情况三、查看日志四、定位原因五、快速解决六、再次查看服务器端口使用情况七、总结一、背景 运维Debezium集群,停止Debezium集群后,再次启动Debezium集群提示端口被…

一个注解让你的项目减少30%SQL代码量

今天给大家介绍一个很好用的开源项目&#xff1a;easy_trans&#xff0c;它能让你的项目减少30%的SQL代码量&#xff0c;接下来让我们进一步了解它。 什么是Easy_Trans Easy Trans是一款用于做数据翻译的代码辅助插件&#xff0c;利用MyBatis Plus/JPA/BeetlSQL 等ORM框架的能…

算法----使二进制字符串字符交替的最少反转次数

题目 给你一个二进制字符串 s 。你可以按任意顺序执行以下两种操作任意次&#xff1a; 类型 1 &#xff1a;删除 字符串 s 的第一个字符并将它 添加 到字符串结尾。 类型 2 &#xff1a;选择 字符串 s 中任意一个字符并将该字符 反转 &#xff0c;也就是如果值为 ‘0’ &…