利用快慢指针,求链表的中间结点,判断链表是否是环形链表

news2024/11/26 15:42:06

前言

(1)在学习数据结构链表部分的时候,老师给出了几个题目。其中两个题目采用了快慢指针的技术,感觉有意思,于是写一篇博客记录一下。

快慢指针

(1)我们先来介绍一下快慢指针技术。这个说起来其实很简单,就是龟兔赛跑问题。
(2)兔子跑的比乌龟快,我们可以利用这个特性,来解决一些实际按理。

求链表的中间结点

原题链接

(1)原题链接:https://leetcode.cn/problems/middle-of-the-linked-list/description/

分析

(1)此题的核心目标是找到单链表的中间节点。如果是顺序表,就非常简单,直接采用sizeof()知道顺序表的大小,然后直接访问就可以了。
(2)但是单链表的存储不是连续的,想要找到某个元素,必须从头寻找。
(3)从头寻找又会有一个问题,因为这里是单链表,你只能往前走,不能回退。所以就算你遍历了整个链表,知道了链表的长度之后,还需要从头遍历链表,找到中间位置返回。假设这个链表长度是N,那么你就需要遍历1.5N次。
(4)这样虽然可行,但是很麻烦,因此我们可以采用快慢链表的方式,很好的解决这个问题。为什么这么说呢?因为我们需要找到单链表的中间位置,于是可以建立一个速度是乌龟一倍的兔子,如果兔子跑到了终点了,那么乌龟就正好是在中间位置。因此我们看下面这张图分析:
<1>假设这个单链表是偶数个,按照下面这个流程来,我们会发现跑的快的兔子最终会跑出赛道,而乌龟正好是在中间位置的第二个节点,完美符合要求。因此,单链表为偶数个,结束条件为fast==NULL。
<2>假设单链表是奇数个,按照下面流程来看,我们可以知道,兔子正好跑到终点,再跑就跑出赛道了。因此,单链表为奇数个,结束条件为fast–>==NULL。

在这里插入图片描述

代码

根据上面的解析,我们可以写出下面这段代码

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


struct ListNode* middleNode(struct ListNode* head){
    struct ListNode* slow = head,*fast = head;
    while(fast != NULL && fast->next !=NULL)
    {
        slow = slow->next;
        fast = fast->next->next;
    }
    return slow;
}

判断链表是否是环形链表

原题链接

原题链接:https://leetcode.cn/problems/linked-list-cycle/description/

分析

(1)这个链表可能是一个环,我们需要进行判断,那么我们可以让兔子和乌龟在这个赛道里面跑。因为兔子比乌龟的速度快,所以这个环赛道里面,兔子铁定可以追上乌龟的。

在这里插入图片描述

(2)但是,各位需要注意一个点,只要时间足够,兔子在这个赛道一定可以追上乌龟。可是,兔子追上了乌龟一定会停下来吗?
(3)为什么需要问这个问题呢?因为,我们在编程的时候,都是先让兔子和乌龟跑一次,然后判断乌龟和兔子位置是否重叠。如果兔子和乌龟位置重叠,那么说明这是一个环形链表,如果兔子一直跑,发现能够跑到尽头,那么就说明这不是一个环形链表。
(4)那么我们想一下,如果这是一个环形链表,时间足够,兔子是肯定可以追上乌龟的,但是在进行判断的时候,兔子和乌龟的速度会重合吗?
(5)为了解决这个问题,我们可以画出下面这张图:
<1>假设乌龟进入环形区了,兔子肯定在这里面跑了一段时间了,现在是兔子追乌龟的过程。这个时候兔子距离乌龟n个元素。
<2>分析到这里,这个问题就很简单了,说白了就是一个小学的数学问题。因为兔子比乌龟速度要快,所以我们可以假设乌龟是不运动的,兔子的速度就是比乌龟快的那一部分。
<3>假设乌龟速度是每次走1个元素,兔子是每次走2个元素。那么按照上面分析,让乌龟不动,兔子移动,那么兔子的速度就是每次走一个元素。
<4>最终兔子走n次可以追上乌龟。

在这里插入图片描述

(6)看了上面的分析,肯定有同学会想,我们可不可以让兔子的速度比乌龟的再快一点呢?我要让乌龟的速度是1,兔子速度是3呢?
<1>现在我们假设这张图的环形是N个元素,乌龟到底环形区的时候,兔子距离乌龟n个元素。为了防止兔子追上了乌龟,但是越过了他,因此我们假设兔子要跑k圈最终才能和乌龟位置重合。
<2>根据上面的假设,我们可以建立下面这个数学模型计算出兔子要跑多少次才能追上乌龟。注意,k可以是0,1,2…的任意整数
k ∗ N + n f a s t − s l o w \frac{k*N+n}{fast-slow} fastslowkN+n
<3>我们一直尝试k的值,最终计算出来的最小整数,就算兔子要跑的次数。
<4>上面我们假设了兔子每次跑3个元素,乌龟每次跑1个元素。因此fast-slow就是2。
<5>我们假设这个环形区N为4,乌龟到达环形区时候,兔子距离他的n为1。那么套入公式就是
k ∗ N + n f a s t − s l o w = k ∗ 4 + 3 2 = 2 ∗ k + 1.5 \frac{k*N+n}{fast-slow} = \frac{k*4+3}{2}= 2*k + 1.5 fastslowkN+n=2k4+3=2k+1.5
<6>发现没有,上面这个条件下,永远不可能算出整数。因此,兔子比乌龟的速度快1个元素才能解决所有可能情况。
<7>这个时候,肯定又有人要说了,那我让兔子比乌龟的速度快1个元素,但是我让乌龟的速度提上来可以不。可以,当然可以,但是不推荐,你速度提上来了,但是程序运行速度就不一定提上来了,因为你乌龟看起来每次是多走了一点距离,但是对于程序而言,还是一步一步的走,不过不是每步都进行了一次判断而言。

在这里插入图片描述

代码

(1)根据上面的分析,我们可以写出如下代码

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

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

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

相关文章

Java性能分析中常用命令和工具

当涉及到 Java 性能分析时&#xff0c;有一系列强大的命令和工具可以帮助开发人员分析应用程序的性能瓶颈、内存使用情况和线程问题。以下是一些常用的 Java 性能分析命令和工具&#xff0c;以及它们的详细说明和示例。 以下是一些常用的性能分析命令和工具汇总&#xff1a; …

vscode远程调试PHP代码

目录 一、准备工作 二、ssh连接和xdebug配置 1.ssh连接 2.xdebug配置 三、xdebug调试&#xff0c;访问 一、准备工作 1.安装vscode里面的两个扩展 2.安装对应PHP版本的xdebug 去xdebug官方&#xff0c;复制自己的phpinfo源码到方框里&#xff0c;再点击Analyse Xdebug: …

【⑫MySQL | 约束(二)】外键 | 默认值 | 检查约束 — 综合案例

前言 ✨欢迎来到小K的MySQL专栏&#xff0c;本节将为大家带来MySQL外键 | 默认值 | 检查约束 以及综合案例的分享✨ 目录 前言6. 外键约束(FOREIGN KEY,FK)7. 默认值约束和检查约束8. 综合实战总结 6. 外键约束(FOREIGN KEY,FK) 前面介绍的完整性约束都是在单表中进行设置&…

VB6创建ActiveX exe简单方法

VB6创建的COM即可以是线程内的DLL&#xff0c;也可以是线程外独立的EXE&#xff0c;有些32位的旧东西做activex.exe封装后在新硬件新软件x64位上用还是可以的。其实activex DLL和activeX EXE主要功能并不需要改变。activex DLL可以是如下的样子&#xff1a; 一个主工程文件&…

​​Linux 信号量​​​​

信号量的产生原因 我们将可能会被多个执行流同时访问的资源叫做临界资源&#xff0c;临界资源需要进行保护否则会出现数据不一致等问题。 当我们仅用一个互斥锁对临界资源进行保护时&#xff0c;相当于我们将这块临界资源看作一个整体&#xff0c;同一时刻只允许一个执行流对…

WPF入门到精通:2.WPF常用控件及布局

WPF&#xff08;Windows Presentation Foundation&#xff09;是一个用于构建 Windows 应用程序的框架&#xff0c;它提供了丰富的控件和布局方式&#xff0c;帮助开发者快速构建出现代化的应用程序。 WPF常用控件 Button 控件 WPF 中最常用的控件之一。它由一个文本标签和一个…

设计模式之迭代器模式(Iterator)的C++实现

1、迭代器模式的提出 在软件开发过程中&#xff0c;操作的集合对象内部结构常常变化&#xff0c;在访问这些对象元素的同时&#xff0c;也要保证对象内部的封装性。迭代器模式提供了一种利用面向对象的遍历方法来遍历对象元素。迭代器模式通过抽象一个迭代器类&#xff0c;不同…

list使用

list的使用于string的使用都类似&#xff0c;首先通过查阅来看list有哪些函数&#xff1a; 可以看到函数还是蛮多的&#xff0c;我们值重点一些常用的和常见的&#xff1a; 1.关于push_back,push_front,和对应迭代器的使用 //关于push_back和push_front void test_list1() {l…

算法通关村——字符串反转问题解析

1. 反转字符串 反转字符串 编写一个函数&#xff0c;其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。 不要给另外的数组分配额外的空间&#xff0c;你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。 1.1 交换 这一题的思路还是简单的&…

Flink状态和状态管理

1.什么是状态 官方定义&#xff1a;当前计算流程需要依赖到之前计算的结果&#xff0c;那么之前计算的结果就是状态。 这句话还是挺好理解的&#xff0c;状态不只存在于Flink&#xff0c;也存在生活的方方面面&#xff0c;比如看到一个认识的人&#xff0c;如何识别认识呢&am…

程序的编译流程

程序的编译过程大致可以分为以下几个阶段

八大排序算法 - Java实现

冒泡排序 排序原理&#xff1a; 比较相邻的元素。如果前一个元素比后一个元素大&#xff0c;就交换这两个元素的位置。对每一对相邻元素做同样的工作&#xff0c;从开始第一对元素到结尾的最后一对元素。最终最后位置的元素就是最大值 代码实现&#xff1a; import java.uti…

图神经网络学习

入门 目的&#xff1a;训练一个图模型&#xff0c;使得该图模型可以区分图上的黄色节点和绿色节点。 特征作为图的节点&#xff0c;颜色就是图的分类。 图的度的概念&#xff1a;与节点相连的条数。 邻接表记录的是后续邻居的信息&#xff1b; 在新闻推荐中&#xff0c;节点是…

2021年09月 C/C++(三级)真题解析#中国电子学会#全国青少年软件编程等级考试

第1题&#xff1a;余数相同问题 已知三个正整数 a&#xff0c;b&#xff0c;c。 现有一个大于1的整数x&#xff0c;将其作为除数分别除a&#xff0c;b&#xff0c;c&#xff0c;得到的余数相同。 请问满足上述条件的x的最小值是多少? 数据保证x有解。 输入 一行&#xff0c;三…

微服务中间件--Nacos

Nacos 1. Nacos入门a.服务注册到Nacosb.Nacos服务分级存储模型c.NacosRule负载均衡d.服务实例的权重设置e.环境隔离 - namespacef.Nacos和Eureka的对比 2. Nacos配置管理a.统一配置管理b.配置热更新c.多环境配置共享 1. Nacos入门 Nacos是阿里巴巴的产品&#xff0c;现在是Spr…

【前端|JS实战第1篇】使用JS来实现属于自己的贪吃蛇游戏!

前言 贪吃蛇游戏是经典的小游戏&#xff0c;也是学习前端JS的一个很好的练习项目。在本教程中&#xff0c;我们将使用 JavaScript 来逐步构建一个贪吃蛇游戏。我们会从创建游戏区域开始&#xff0c;逐步添加蛇的移动、食物的生成以及游戏逻辑等功能。 &#x1f680; 作者简介&a…

tcl学习之路(五)(Vivado时序约束)

1.主时钟约束 主时钟通常是FPGA器件外部的板机时钟或FPGA的高速收发器输出数据的同步恢复时钟信号等。下面这句语法大家一定不会陌生。该语句用于对主时钟的名称、周期、占空比以及对应物理引脚进行约束。 create_clock -name <clock_name> -periood <period> -wa…

电影《孤注一掷》感触、计算机底层二进制与十进制的转换

今天&#xff0c;我与媳妇一同在商场吃完午餐&#xff0c;正值天空绵绵细雨。近期&#xff0c;听闻一部名为《孤注一掷》的电影&#xff0c;其主人公是一位程序员&#xff0c;故事情节围绕境外电信诈骗展开&#xff0c;引发了广泛的关注。身为一名程序员&#xff0c;我对与电信…

DSO 系列文章(2)——DSO点帧管理策略

文章目录 1.点所构成的残差Residual的管理1.1.前端残差的状态1.2.后端点的残差的状态1.3.点的某个残差的删除 2.点Point的管理2.1.如何删除点——点Point的删除2.2.边缘化时删除哪些点&#xff1f; 3.帧FrameHessian的管理 DSO代码注释&#xff1a;https://github.com/Cc19245/…

Vulnhub: DriftingBlues: 2靶机

kali&#xff1a;192.168.111.111 靶机&#xff1a;192.168.111.207 信息收集 端口扫描 nmap -A -sC -v -sV -T5 -p- --scripthttp-enum 192.168.111.207 80端口的/blog目录为wordpress wpscan收集wordpress用户和爆破密码 wpscan --url http://driftingblues.box/blog -e…