【数据结构】-- 相交链表-环形链表

交叉链表

. - 力扣(LeetCode) 
如果链表的两条链的长度一样,链表两端对齐,解决这个问题将会变得非常简单,直接分别遍历两个链表,想等时的节点即为所求。我们想办法让链表对齐--分别从a和b遍历链表,分别求出以a开始和以b开始时的链表长度,求出a,b之差的绝对值k。然后再让较长一端先走k步,这样就对齐了。然后再同时遍历链表,两端相等时,这个节点即为所求。
其实,这就是一个快慢指针的解法,快慢指针每次都只走一步,只不过快指针先走使链表对齐。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
 typedef struct ListNode ListNode;
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
    ListNode* a = headA;
    ListNode* b = headB;
    int count1 = 0;
    int count2 = 0;
    while(a->next)
    {
        a = a->next;
        count1++;
    } 
    while(b->next)
    {
        b = b->next;
        count2++;
    }
    if (a != b)
    {
        return NULL;
    }
    a = headA;
    b = headB;
    int k = abs(count1 - count2);
    ListNode* LongA = a;
    ListNode* shortB = b;
    if(count2 > count1)
    {
        LongA = b;
        shortB = a;
    }
    while(k--)
    {
        LongA = LongA->next;
    }
    while(shortB && LongA)
    {
        LongA = LongA->next;
        shortB = shortB->next;

        if (shortB == LongA)
        return shortB;
    }

}

环形链表

环形链表 一

 . - 力扣(LeetCode)

如果只用一个指针遍历链表,会在环中死循环。在这到题中我们还是使用快慢指针的解法:定义fast和slow两个指针,fast每次走两步,slow每次走一步。如果没有环,fast会先走到尾节点。如果有环,fast会比slow先到环中,到slow走到环中时便成了追击相遇问题,fast比slow快,总会追到slow,如果fast == slow,就说明链表中有环。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */

 typedef struct ListNode ListNode;
bool hasCycle(struct ListNode *head) {
    ListNode* slow = head;

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

延申讨论 

当fast一次走三步,slow一次走一步的时候还能相遇吗?会不会错过?

设非环部分的长度为L,环的长度为C,fast距slow为N。

当slow进环后每走一步,相差的距离减少2

依次为 N

          N - 2

          N - 4 

           .........

如果N是偶数,那么就可以相遇。如果N为奇数,fast与slow的距离变为C - 1,进入下一次循环,若C - 1为偶数,fast 与slow之间的距离一次依次减少2,最后为0,相遇。若C - 1是奇数,那么fast与slow的距离依次减少2,最后fast与slow又会错过,距离又变为C - 1,依次重复,永远遇不到。

这样算出来,将永远遇不到,但是这样要满足一个条件,N是奇数,C - 1为奇数。我们还有一个条件没有用到fast移动的距离是slow的3倍,以此可得:

                

 2 * L必为偶数,那么若C - 1为奇数,C就为偶数,N必为偶数,所以不相遇的条件不存在。

fast与slow必会相遇。

这种数理上的题就是为了筛选出的,为了考核。虽然可能没什么应用的意义,但是考查了数理能力,在面试的时候解出来会让面试官眼前一亮。

环形链表 二

. - 力扣(LeetCode)

 定义fast和slow两个指针,slow每次走一步,fast每次走两步。设环长为C,非环部分长为L,当slow与fast相遇的时候,slow又走的距离为N。

就和高中的物理题一样,我们要找等式关系。设fast所走的总路程为F,slow的为S,当slow与fast相遇时:

F = L +  N + x * C   (假设fast在环中已经走了x圈)
S = L +  N

F是S的2倍。L + N + x * C = 2( L + N )
化简为:       L = x *C - N  = ( x - 1 ) *  C  + C - N

重新定义一个节点cmp从头开始一步一步走,设slow和fast相交的点为meet,同时开始一步一步走。所以cmp走了( x - 1 ) * C 过后还剩 C - N;meet走了(x - 1)* C回到原点到原点。这时,cmp和meet都相距环的起点C - N。当它们相遇时,这个节点即为所求

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */

 typedef struct ListNode ListNode;
struct ListNode *detectCycle(struct ListNode *head) {
   ListNode* slow = head;

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

centos7中如何全局搜索一下nginx的配置文件?

在CentOS 7中搜索Nginx的配置文件,你可以使用一些常用的命令行工具,比如find、grep等。这些工具可以帮助你在文件系统中查找文件,也可以用来查找Docker容器内部的文件,只要你知道如何访问容器的文件系统。 1. 搜索系统中的Nginx配…

nowcoder——回文结构

链表的回文结构_牛客题霸_牛客网 (nowcoder.com) 我们来分析该题:我们首先要清楚什么是回文结构?其实就是对称结构。如果一个链表呈对称结构就说明该链表具有回文结构。 下面给上一些例子: 那我们怎么判断该链表是否属于回文结构呢&#xf…

Web3 Tools - Base58

Base58编码 Base58编码是一种用于表示数字的非常见的编码方法。它通常用于加密货币领域,例如比特币和其他加密货币的地址表示。 什么是Base58编码? Base58编码是一种将数字转换为人类可读形式的编码方法。与常见的Base64编码不同,Base58编码…

AI智能体|我把Kimi接入了个人微信

大家好,我是无界生长。 最近加入AI学习交流群的小伙伴越来越多,我打算在微信群接入一个聊天机器人,让它协助管理微信群,同时也帮忙给群友解答一些问题。普通的群聊机器人肯定是不能满足需求的,得上AI大模型&#xff0c…

使用 Python 中的 TensorFlow 检测垃圾短信

前言 系列专栏:机器学习:高级应用与实践【项目实战100】【2024】✨︎ 在本专栏中不仅包含一些适合初学者的最新机器学习项目,每个项目都处理一组不同的问题,包括监督和无监督学习、分类、回归和聚类,而且涉及创建深度学…

绘唐3启动器怎么启动一键追爆款3正式版

绘唐3启动器怎么启动一键追爆款3正式版 工具入口 一.文案助手: 【注意!!】如果图片无显示,一般情况下被杀毒拦截,需关闭杀毒软件或者信任文件路径。 win10设置排除文件: 1.【新建工程】使用前先新建工程…

【Flutter】极光推送配置流程(VIVO/OPPO/荣耀厂商通道) 章三

前言 很高兴大家来看小编写的文章~~ 继【Flutter】极光推送配置流程(极光通道/华为厂商/IOS) 章一 继【Flutter】极光推送配置流程(小米厂商通道) 章二 接下配置VIVO/OPPO/华为荣耀的厂商通道 所有截图来源于公司项目,所以会有大量马赛克&am…

5.13作业

使用消息队列实现的2个终端之间的互相聊天 并使用信号控制消息队列的读取方式: 当键盘按ctrlc的时候,切换消息读取方式,一般情况为读取指定编号的消息, 按ctrlc之后,指定的编号不读取,读取其他所有编号的…

Pikachu 靶场 URL 重定向通关解析

前言 Pikachu靶场是一种常见的网络安全训练平台,用于模拟真实世界中的网络攻击和防御场景。它提供了一系列的实验室环境,供安全专业人士、学生和爱好者练习和测试他们的技能。 Pikachu靶场的目的是帮助用户了解和掌握网络攻击的原理和技术,…

Qt与QWebEngineView 交互-调试窗口-JS拓扑图完整示例参考

1:介绍: Qt与QWebEngineView的交互 简介之前文章解释过,链接在下面 传送门:Qt与QWebEngineView 交互完整示例参考_qt qwebview-CSDN博客 一般在使用这种方式时,可能会出现各种问题而不好调试,如果能够像…

【408精华知识】提高外部排序速度的三种方式

文章目录 一、败者树二、置换-选择排序三、最佳归并树 一、败者树 还没写完… 二、置换-选择排序 三、最佳归并树 写在后面 这个专栏主要是我在学习408真题的过程中总结的一些笔记,因为我学的也很一般,如果有错误和不足之处,还望大家在评…

基于Echarts的大数据可视化模板:服务器运营监控

目录 引言背景介绍研究现状与相关工作服务器运营监控技术综述服务器运营监控概述监控指标与数据采集可视化界面设计与实现数据存储与查询优化Echarts与大数据可视化Echarts库以及其在大数据可视化领域的应用优势开发过程和所选设计方案模板如何满足管理的特定需求模板功能与特性…

I. Integer Reaction

Problem - I - Codeforces 看到最小值最大值,二分答案。 思路:每次二分时开两个集合,分别表示 0 0 0颜色和 1 1 1颜色。如果是 c c c颜色,先将值存入 c c c颜色,之后在 ! c !c !c颜色中找大于等于 m i d − a mid - a…

.NET开源、功能强大、跨平台的图表库LiveChart2

LiveCharts2 是 从LiveCharts演变而来,它修复了其前身的主要设计问题,它专注于在任何地方运行,提高了灵活性,并继承LiveCharts原有功能。 极其灵活的数据展示图库 (效果图) 开始使用 Live charts 是 .Net 的跨平台图表库,请访问 https://livecharts.dev 并查看目标平…

括号匹配(栈)

20. 有效的括号 - 力扣(LeetCode) c有栈 但是C语言没有 到那时我们可以自己造 这里的代码是直接调用栈,然后调用 等于三个左括号的任意一个 我们就入栈 左括号(入栈) 右括号 取出栈顶数据,出栈并且进行匹配…

用Transformers实现简单的大模型文本生成

根据输入的prompt,生成一段指定长度的文字。Llama跑起来太慢了,这里用GPT-2作为列子。 from transformers import GPT2LMHeadModel, GPT2Tokenizer import torchtokenizer GPT2Tokenizer.from_pretrained("gpt2") model GPT2LMHeadModel.fr…

VC 编程开发中的 封装类 :log日志类 和SQL server 操作类 源代码

VC 编程开发中的 封装类 :日志类 和SQL server 操作类 源代码 在VC(Visual C)开发中,日志文件输出是一个至关重要的环节,它对于程序调试、问题排查以及系统监控等方面都具有不可替代的作用。以下是对日志文件输出在VC开…

4.2 试编写一程序,要求比较两个字符串STRING1和STRING2所含字符是否相同,若相同则显示“MATCH”,若不相同则显示“NO MATCH”

方法一:在程序内部设置两个字符串内容,终端返回是否匹配 运行效果: 思路: 1、先比较两个字符串的长度,如果长度不一样,则两组字符串肯定不匹配;如果长度一样,再进行内容的匹配 2、如…

CSS学习笔记之中级教程(一)

1、CSS 布局 - display 属性 1.1 display 属性 display 属性是用于控制布局的最重要的 CSS 属性。 display 属性规定是否/如何显示元素。 每个 HTML 元素都有一个默认的 display 值,具体取决于它的元素类型。大多数元素的默认 display 值为 block 或 inline。 …

R语言数据分析案例-巴西固体燃料排放量预测与分析

1 背景 自18世纪中叶以来,由于快速城市化、人口增长和技术发展,导致一氧化二氮(N2O)、 甲烷(CH4)和二氧化碳(CO 2)等温室气体浓度急剧上升,引发了全球变暖、海平面上 升…