【数据结构】链表OJ面试题4(题库+解析)

 1.前言 

前五题在这http://t.csdnimg.cn/UeggB

后三题在这http://t.csdnimg.cn/gbohQ

给定一个链表,判断链表中是否有环。http://t.csdnimg.cn/Rcdyc 

记录每天的刷题,继续坚持!

2.OJ题目训练

10. 给定一个链表,返回链表开始入环的第一个结点。 如果链表无环,则返回 NULL

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

本题是上一题(链接在上)的延续,不清楚的小码喵可以去上一篇博客观看一下。

方法一

思路

为了方便分析,我们把示例图简化一下涉及一点数学思维,大家做好准备。

我们依然按照上题来定义两个快慢指针,fast一次前进两步,slow一步

如果为环,那么fast和slow终会在环中相遇,这里假设已经相遇了。

注意以下的单位为节点数

入口点:链表开始入环的第一个节点

相遇点:fast和slow相遇的节点

假设起点到入口点长度:L
假设环的周长是:C
假设入口点到相遇点的长度是:X

由于fast走过的距离是链表起点>>入口点 + 在环中移动的圈数(必须转圈才能做到跟slow相遇)+ 入口点到相遇点的距离

slow是链表起点>>入口点 + 入口点到相遇点的距离

fast走的距离是slow的两倍,那么我们可以得出:

fast移动的距离:L+C+X

slow移动的距离:L+X

两倍关系:L+C+X=2(L+X)

但是上面fast公式的C我们要画上一个问号,因为fast可能在环中不止会转一圈,可能会转很多圈(环足够小),所以我们再改进公式得到:

fast移动的距离:L+n*C+X         n为fast在环中循环的圈数

slow移动的距离:L+X

两倍关系:L+n*C+X=2(L+X)

                

        L = n*C - X

得出关系:链表头走到起点的距离 = n倍的周长再减去相遇点到起点的距离

进而得出:一个指针从表头走,一个指针从相遇点走,那么他们会在入口点相遇!

附源代码

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode *detectCycle(struct ListNode *head) {
    struct ListNode *fast;
    struct ListNode *slow;
    fast = slow = head;
    while(fast&&fast->next&&slow->next)
    {
        fast=fast->next->next;
        slow=slow->next;
        if(fast == slow)    //相遇
        {
            struct ListNode *tou = fast;    //相遇点,相遇时再创建节约空间
            while(head!=tou)    //向下继续走,直到他们相遇就是起点
            {
                head = head ->next;
                tou = tou -> next;
            }
            return tou; 
        }
        
    }

    return NULL;    //无法相遇则不为环形链表
}

方法二

本题还有一个极为简单的解法,但是相对繁琐,我们要用到之前刷过的一题。(CV一下)

这里给大家一个链接看看大家能不能自己想出方法:160. 相交链表 - 力扣(LeetCode)

思路

我们可以利用更新奇的办法:分割链表,来把一个链表变为两个,再利用相交链表的方法来求出他们的起点。

当fast和slow相遇时,我们记录这个相遇点

之后再记录下一个点,我们就可以把相遇点断开,称为newhead

这样,环形链表,和newhead组成的表,就可以运用相交链表的方法,达到入口点既交点的节点了

如图,红色和紫色,既两个相交链表

注意事项

  • 相交链表那块要足够清楚,我们是将问题牵线搭桥到那里去的,所以要足够理解
  • 直接CV

附源代码

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

//返回相交链表相交节点的函数

struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
    struct ListNode *curA=headA;
    struct ListNode *curB=headB;
    int lenA=1,lenB=1;  //链表的长度至少为1
    while(curA->next)   //计算链表A的长度及尾节点
    {
        lenA++; //顺便计算表长
        curA=curA->next;
    }
    while(curB->next)
    {
        lenB++;
        curB=curB->next;
    }
    if(curA!=curB)
    {
        return NULL;    //两边的为节点不相同,那根本不是相交链表
    }

    int gap=abs(lenA-lenB); //abs为取绝对值
    struct ListNode *longlist=headA;    //假设A为长节点,这里我们利用替身来表示长表
    struct ListNode *shortlist=headB;   //就可以节省很多判断语句
    if(lenB>lenA)                       //若B长,侧替换
    {
        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;
    struct ListNode *slow;
    fast = slow = head;
    while(fast&&fast->next&&slow->next)
    {
        fast=fast->next->next;
        slow=slow->next;
        if(fast == slow)    //相遇
        {
            struct ListNode *tou = fast;    //相遇点,相遇时再创建节约空间
            struct ListNode *newhead = tou->next; //新表头为相遇的下一个节点
            tou->next = NULL;   //将相遇点断开
            return getIntersectionNode(newhead, head);
        }
    }
    return NULL;    //无法相遇则不为环形链表
}

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

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

相关文章

【doghead】uv_loop_t的创建及线程执行

worker测试程序,类似mediasoup对uv的使用,是one loop per thread 。创建一个UVLoop 就可以创建一个uv_loop_t Transport 创建一个: 试验配置创建一个: UvLoop 封装了libuv的uv_loop_t ,作为共享指针提供 对uv_loop_t 创建并初始化

【CV论文精读】【MVDet】Multiview Detection with Feature Perspective Transformation

0.论文摘要 合并多个摄像机视图进行检测减轻了拥挤场景中遮挡的影响。在多视图检测系统中,我们需要回答两个重要问题。首先,我们应该如何从多个视图中聚合线索?第二,我们应该如何从空间上相邻的位置聚集信息?为了解决…

【机器学习】数据清洗之识别缺失点

🎈个人主页:甜美的江 🎉欢迎 👍点赞✍评论⭐收藏 🤗收录专栏:机器学习 🤝希望本文对您有所裨益,如有不足之处,欢迎在评论区提出指正,让我们共同学习、交流进步…

Android Studio 安装Flutter插件但是没法创建项目

Android Studio 安装Flutter插件但是没法创建项目 如果你在Android Studio已经安装了Dart、Flutter插件,但是不能创建Flutter项目。 原因是因为Android Studio的版本更新,Android APK Support这个插件没被选中。 一旦勾选这个插件之后,就能…

超级干货:ArcGIS的那些花样技巧

本篇是工作过程中收集的一些ArcGIS相关的技巧和问题解决思路。总有一些坑是你也踩过的,希望可以帮到你。 1、筛选工具中的SQL语句用法 DLMC IN (水田,水浇地) 筛选DLMC字段值为水田或水浇地的图斑 DLMC IS NOT NULL 筛选DLMC字段值不为空的图斑 DLMC LIKE(%水%…

【Linux】线程池线程安全的单例模式和STL读者写者问题

需要云服务器等云产品来学习Linux的同学可以移步/–>腾讯云<–/官网&#xff0c;轻量型云服务器低至112元/年&#xff0c;优惠多多。&#xff08;联系我有折扣哦&#xff09; 文章目录 1. 线程池1.1 线程池是什么1.2 为什么要有线程池1.3 线程池的应用场景1.4 线程池的任…

Linux 文件比较工具

在Linux系统中&#xff0c;文件比较是一种常见的任务&#xff0c;用于比较两个文件之间的差异。文件比较可以帮助我们找出两个文件的不同之处&#xff0c;或者确定它们是否完全相同。在Linux中&#xff0c;有多种方法可以进行文件比较。 1. diff 在Linux中&#xff0c;diff命…

逐鹿比特币生态,Elastos 携新作 BeL2「重出江湖」

撰文&#xff1a;Babywhale&#xff0c;Techub News 文章来源Techub News&#xff0c;搜Tehub News下载查看更多Web3资讯。 刚刚过去的 2023 年&#xff0c;「比特币生态」成为了市场的绝对焦点之一。从铭文开始&#xff0c;到重新走进大众视野的 Stacks 与比特币闪电网络&am…

Apktool任意文件写入漏洞分析 CVE-2024-21633

前置知识 在复现该漏洞前&#xff0c;有必要了解Apktool和resources.arsc相关的基础知识&#xff0c;方便理解后续POC的构造。 Apktool是一款流行的开源逆向工程软件&#xff0c;用于反编译和编译Android应用&#xff0c;因此&#xff0c;Apktool被许多其他逆向工程软件集成。…

Conda历史版本下载地址和python对应关系

一、前言 因为Conda安装版本问题&#xff0c;带来了很多问题&#xff0c;虽然不能直接确定二者之间的关系&#xff0c;但是安装指定版本的conda,确实是一个比较好的方法。特此记忆。 二、下载地址 下载最新版本&#xff1a;Free Download | Anaconda 下载历史版本&#xff…

ssm+vue的校园一卡通密钥管理系统(有报告)。Javaee项目,ssm vue前后端分离项目。

演示视频&#xff1a; ssmvue的校园一卡通密钥管理系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;ssm vue前后端分离项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系…

【JS逆向八】逆向某企查网站的headers参数,并模拟生成 仅供学习

逆向日期&#xff1a;2024.02.07 使用工具&#xff1a;Node.js 加密方法&#xff1a;未知 / 标准库Hmac-SHA512 文章全程已做去敏处理&#xff01;&#xff01;&#xff01; 【需要做的可联系我】 可使用AES进行解密处理&#xff08;直接解密即可&#xff09;&#xff1a;AES加…

PdfFactory Pro软件下载以及序列号注册码生成器

PdfFactory Pro注册机是一款针对同名虚拟打印机软件所推出的用户名和序列号生成器。PdfFactory Pro是一款非常专业的PDF虚拟打印软件&#xff0c;通过使用这款注册机&#xff0c;就能帮助用户免费获取注册码&#xff0c;一键激活&#xff0c;永久免费使用。 pdffactory7注册码如…

传输层协议 ——— TCP协议

TCP协议 TCP协议谈谈可靠性为什么网络中会存在不可靠&#xff1f;TCP协议格式TCP如何将报头与有效载荷进行分离&#xff1f;序号与确认序号 确认应答机制&#xff08;ACK&#xff09;超时重传机制连接管理机制三次握手四次挥手 流量控制滑动窗口拥塞控制延迟应答捎带应答面向字…

Java并发基础:LinkedTransferQueue全面解析!

内容概要 LinkedTransferQueue类实现了高效的线程间数据传递&#xff0c;支持等待匹配的生产者-消费者模式&#xff0c;基于链表的无界设计使其在高并发场景下表现卓越&#xff0c;且无需担心队列溢出&#xff0c;丰富的方法和良好的可扩展性满足了各种复杂应用场景的需求。 …

【Godot4.2】文件系统自定义控件 - FileSystemTree

FileSystemTree B站【Godot4.2】文件系统自定义节点 - FileSystemTree 概述 在Godot设计编辑器插件或应用程序时&#xff0c;可能需要涉及文件系统的显示&#xff0c;比如文件夹或文件的树形列表。 我们可以用Godot的Tree控件快速书写相应的功能&#xff0c;但是为了复用到…

华为OD机试C卷 - 最富裕的小家庭( Python C C++ JavaGo JS PHP)

题目描述 在一颗树中&#xff0c;每个节点代表一个家庭成员&#xff0c;节点的数字表示其个人的财富值。一个小家庭由一个节点及其直接相连的子节点组成。 现在给定一颗树&#xff0c;我们需要计算最富裕的小家庭的财富和。 输入描述 输入包括以下几行&#xff1a; 一个整…

Project2013下载安装教程,保姆级教程,附安装包和工具

前言 Project是一款项目管理软件&#xff0c;不仅可以快速、准确地创建项目计划&#xff0c;而且可以帮助项目经理实现项目进度、成本的控制、分析和预测&#xff0c;使项目工期大大缩短&#xff0c;资源得到有效利用&#xff0c;提高经济效益。软件设计目的在于协助专案经理发…

2024年【广东省安全员B证第四批(项目负责人)】考试及广东省安全员B证第四批(项目负责人)考试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 广东省安全员B证第四批&#xff08;项目负责人&#xff09;考试考前必练&#xff01;安全生产模拟考试一点通每个月更新广东省安全员B证第四批&#xff08;项目负责人&#xff09;考试题题目及答案&#xff01;多做几…

基于AST实现一键自动提取替换国际化文案

背景&#xff1a;在调研 formatjs/cli 使用&#xff08;使用 formatjs/cli 进行国际化文案自动提取 &#xff09;过程中&#xff0c;发现有以下需求formatjs/cli 无法满足&#xff1a; id 需要一定的语义化&#xff1b; defaultMessage和Id不能直接hash转换&#xff1b; 需要…