链表经典题目:环形链表问题(LeetCode141.环形链表、LeetCode142.环形链表Ⅱ)

news2024/10/7 9:24:24

📇文章目录

  • 📜 LeetCode141. 环形链表
      • 🔶题目描述
      • 🔷思路分析
      • ✔️代码实现
  • 📜 LeetCode142.环形链表Ⅱ
      • 🔶题目描述
      • 🔷思路①
      • ✔️代码实现
      • 🔷思路②
  • 📒总结

📜 LeetCode141. 环形链表

🔶题目描述

题目戳➡️LeetCode141.环形链表

给你一个链表的头节点 head ,判断链表中是否有环.
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。
为了表示给定链 表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。
注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。 如果链表中存在环 ,则返回 true 。 否则,返回 false
在这里插入图片描述

🔷思路分析

   错误思路:

  • 可能刚上来我们会这样想,遍历整个链表,如果找不到空说明就有环
    但是有没有考虑过,如果链表有环,那么永远找不到空! 不就死循环了吗
    你的程序就崩溃了 所以这种思路是错误的!

那么正确的思路是要怎么做呢?
➡️ 快慢指针

定义一个fast指针 和一个 slow指针,

  • fast一次走两步,slow一次走一步
    那么 ,如果fast走到尾 那么slow刚好走了链表的一半
    如果fast走到了空 说明链表没有环
  • 如果fast走到尾部 还没有停止 说明链表有环
    fast进入环之后 就变成了追及问题(龟兔赛跑)
    –那么我们就有思路了:如果快指针可以追得上满指针 说明有环!
    –反之无环!

但这时候又会有一个问题:链表的节点数是奇数还是偶数呢?
让我们画图分析:
➡️

  • 奇数情况:在这里插入图片描述
  • 偶数情况
    在这里插入图片描述
    总结: 只要fastfast->next 有一个可以走到空 说明链表无环
                否则一定有环,那么当fast追上slow的时候 返回真即可!

在这里插入图片描述

✔️代码实现

bool hasCycle(struct ListNode *head) {
struct ListNode* fast=head,*slow=head;
 	//定义一个快指针和慢指针
  //快指针一次走一步 慢指针一次走两步
  // 如果快指针走到空了 还没有找到交点 说明!没有环
  while(fast&&fast->next)
  {
      fast=fast->next->next;
      slow=slow->next;
      //如果fast追上slow 
      if(fast==slow)
      {
          return true;
      }
  }
  return false;
}

📜 LeetCode142.环形链表Ⅱ

🔶题目描述

题目戳➡️LeetCode142.环形链表Ⅱ

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

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

🔷思路①

  上一个题我们可以挺容易的消除如何判断是不是有环,因为我们只需要判断有没有即可,不需要找出具体的在哪。但是这个题要求我们找出他的入环节点 这要怎么找呢?
其实这个题用到了一点数学知识,请听我分析:
首先还是利用快慢指针,定义一个快指针fast和一个慢指针slow,快指针一次走两步,慢指针一次走一步,然后如果有环,那么标记fastslow的相遇节点为meet 然后这个时候meethead同时开始
向后走,等到他俩相遇的时候,这时候的节点就是入环的第一个节点!
画图分析:
在这里插入图片描述
在这里插入图片描述

  • 所以 由上面的公式化简一下就得到:L=(N-1)*C+(C-K)
    从meet点开始转动N-1圈 再走C-K步 就等于 L的长度
    如果N=1的时候 那么L=C-K
    所以如果一个点在meet开始走,一个点在head开始走,那么 当二者相遇的时候,一定是在入环点!

✔️代码实现

代码就很简单了:

struct ListNode *detectCycle(struct ListNode *head) {
  struct ListNode* fast=head;
  struct ListNode* slow=head;
  while(fast && fast->next)
  {
      fast=fast->next->next;
      slow=slow->next;
      //当快指针和慢指针相遇的时候 
      if(fast==slow)
      {
          struct ListNode* meet=fast;
          while(meet!=head)
          {
              meet=meet->next;
              head=head->next;
          }
          //相交的地方也就是 入环的节点!
          return meet;
      }
  }
  return NULL;
}

🔷思路②

还有一种思路就是
如果我们在fastslow相遇的点meet处切开会发生什么呢?
如图:
在这里插入图片描述
是不是有点熟悉 ?没错!链表相交

那么解题思路就是:
首先找到meet节点,然后meet的下一个节点(nehead) 作为一个新的链表的头部,meet作为尾节点 ,所以这就变成了两个链表相交
所以我们遍历两个单链表找出各自的长度,让长的链表先走,走到二者长度相等的时候,一次比较两个链表的每一个节点,如果有相等n那么直接返回即可,如果没有相等的节点,那么返回空

📒总结

🌟🌟🌟
环形链表问题在面试中是经常爱考的,你有没有发现环形链表的题目代码都没有很难,一般是思路难以想到,所以人家考你的是思路,并不真的会纠你代码写的怎么样!
对于环形链表①,如果面试官这样问你:

  • 快指针必须一次走2步吗?可以一次走3步,走4步可以吗?你会怎么回答?
  • 怎么证明快指针一次走2步一定可以追上?

这里我们简单证明一下:

➡️快指针一次走2步那么一定可以追得上

首先需要知道,fast什么时候开始追击slow
因为fast首先进入环,在slow进环之前,二者的运动路径并不一样!只有当slow也开始进环,才开始所谓的追及问题
假设slow进环以后,fastslow的距离是N
那么fast开始追击slow,二者相对速度为1 ,在追击过程中,它们之间的距离每一次都缩小1
所以距离的变化为:N–> N-1 -->N-2–>···->3–>2–>1–>0
所以一定可以追得上!

➡️可以一次走3步吗

假设slow进环的时候以后,fast与slow的距离为N,环的大小是C
这时候,如果fast开始追击slowfast一次走3步,slow一次走1步,
他们之间的距离一次缩小2步

  • 如果N为偶数
     那么N的变化为:N->N-2->N-4->···->4->2->0 显然可以相遇
  • 如果N为奇数
     那么N的变化为: N->N-2->N-4->···->3->1->-1!
     那么 slowfast之间的距离为-1(擦肩而过!) , 他们之间的距离变成了C-1 这时候如果C-1为偶数那么可以相遇,如果C-1为奇数那么永远不会相遇!
    画图看一下:
    在这里插入图片描述

🌟🌟🌟


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

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

相关文章

父亲节马上到了-和我一起用Python写父亲节的祝福吧

前言 让我们一起用Python写一段父亲节的祝福吧 📝个人主页→数据挖掘博主ZTLJQ的主页 个人推荐python学习系列: ☄️爬虫JS逆向系列专栏 - 爬虫逆向教学 ☄️python系列专栏 - 从零开始学python 话不多说先上代码 import tkinter as tk from doctest imp…

【GD32F303红枫派使用手册】第十六节 USART-DMA串口收发实验

16.1 实验内容 通过本实验主要学习以下内容: 串口DMA工作原理 使用DMA进行串口收发 16.2 实验原理 16.2.1 串口DMA工作原理 在前面ADC章节中,我们介绍了DMA的工作原理,这里就不多做介绍。从GD32F303用户手册中可以查到,各串…

CrossOver 2024软件安装包下载

CrossOver不像Parallels或VMware的模拟器,而是实实在在Mac OS X系统上运行的一个软件。CrossOvers能够直接在Mac上运行Windows软件与游戏,而不需虚拟机。它为Windows软件提供所需的资源,以达到在Mac OS X系统上运行Windows程序的目的。 安 装…

Android屏幕旋转流程(1)

(1)Gsensor的注册和监听 App -->I2C过程:App通过SensorManager.getSystemServer调用到SystemSensorManager,SystemSensorManager通过jni调用到SensorManager.cpp,后通过binder调用到SensorService。SensorService通…

使用Python和TCN进行时间序列预测:一个完整的实战示例

使用Python和TCN进行时间序列预测:一个完整的实战示例 时间卷积网络(TCN)已被证明在处理序列数据方面表现出色,尤其是在需要捕获长期依赖关系的任务中。在本文中,我们将通过一个简单的例子,展示如何使用Py…

洗地机哪款好?洗地机十大名牌排行榜

随着科技的发展,各种家居清洁工具层出不穷,为我们的生活带来了诸多便利。在众多清洁工具中,洗地机的清洁效果更受大家喜爱,它能够完美解决了扫地机无法做到的干湿垃圾“一遍清洁”效果,而且几乎能解决日常生活中所有的…

【Pandas驯化-02】pd.read_csv读取中文出现error解决方法

【Pandas】驯化-02pd.read_csv读取中文出现error解决方法 本次修炼方法请往下查看 🌈 欢迎莅临我的个人主页 👈这里是我工作、学习、实践 IT领域、真诚分享 踩坑集合,智慧小天地! 🎇 相关内容文档获取 微信公众号 &…

微型操作系统内核源码详解系列五(1):arm cortex m3架构

系列一:微型操作系统内核源码详解系列一:rtos内核源码概论篇(以freertos为例)-CSDN博客 系列二:微型操作系统内核源码详解系列二:数据结构和对象篇(以freertos为例)-CSDN博客 系列…

【2024最新华为OD-C/D卷试题汇总】[支持在线评测] 连续区间和(100分) - 三语言AC题解(Python/Java/Cpp)

🍭 大家好这里是清隆学长 ,一枚热爱算法的程序员 ✨ 本系列打算持续跟新华为OD-C/D卷的三语言AC题解 💻 ACM银牌🥈| 多次AK大厂笔试 | 编程一对一辅导 👏 感谢大家的订阅➕ 和 喜欢💗 📎在线评测链接 连续区间和(100分) 🌍 评测功能需要订阅专栏后私信联系清隆…

python如何对list求和

如何在Python中对多个list的对应元素求和,前提是每个list的长度一样。比如:a[1,2,3],b[2,3,4],c[3,4,5],对a,b,c的对应元素…

RN6752V1 高性能AHD转MIPIDVPBT656BT601芯片方案,目前适用于车载方案居多

RN6752V1描述: RN6752V1是一种模拟高清晰度(模拟高清)视频解码器IC,专为汽车应用而设计。它集成了所有必要的功能块: AFE,PLL,解码逻辑,MIPI和I2C接口等,在一个小的5mm …

C语言杂谈:结构体内存对齐

#include<stdio.h> struct S1 {char c1;int i;char c2; }; struct S2 {char c1;char c2;int i; }; int main() {printf("%d\n", sizeof(struct S1));printf("%d\n", sizeof(struct S2));return 0; } 看上面的代码&#xff0c;我们想想应该会输出什么…

Oracle备份失败处理,看这一篇就够了!

作者&#xff1a;IT邦德 中国DBA联盟(ACDU)成员&#xff0c;10余年DBA工作经验&#xff0c; Oracle、PostgreSQL ACE CSDN博客专家及B站知名UP主&#xff0c;全网粉丝10万 擅长主流Oracle、MySQL、PG、高斯及Greenplum备份恢复&#xff0c; 安装迁移&#xff0c;性能优化、故障…

GDB:从零开始入门GDB

目录 1.前言 2.开启项目报错 3.GDB的进入和退出 4.GDB调试中查看代码和切换文件 5.GDB调试中程序的启动和main函数传参 6.GDB中断点相关的操作 7.GDB中的调试输出指令 8.GDB中自动输出值指令 9.GDB中的调试指令 前言 在日常开发中&#xff0c;调试是我们必不可少的技能。在专业…

【每日刷题】Day65

【每日刷题】Day65 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;每日刷题&#x1f34d; &#x1f33c;文章目录&#x1f33c; 1. LCR 175. 计算二叉树的深度 - 力扣&#xff08;LeetCode&#xff09; 2. 序列找数_牛客题霸_牛客网…

超详解——Python 字典详解——小白篇

目录 1. 创建字典 示例&#xff1a; 2. 访问字典中的元素 示例&#xff1a; 3. 修改字典元素 示例&#xff1a; 4. 删除字典元素 示例&#xff1a; 5. 查找元素是否是字典的键 示例&#xff1a; 6. 标准类型操作符 获取字典长度 合并两个字典 7. 常用内置函数 k…

mysql 8 创建用户,并对用户授权

创建用户&#xff1a; 对MySQL创建新用户。命令如下&#xff1a; create user devuser% identified by 123456; 授予权限 grant all privileges on joolun_ry.* to devuser% with grant option; 参数说明&#xff1a; joolun_ry&#xff1a;表明对那个库进行授权&#xf…

SpringCloud跨服务远程调用

随着项目的使用者越来越多&#xff0c;项目承担的压力也会越来越大&#xff0c;为了让我们的项目能服务更多的使用者&#xff0c;我们不得不需要把我们的单体项目拆分成多个微服务&#xff0c;就比如把一个商城系统拆分成用户系统&#xff0c;商品系统&#xff0c;订单系统&…

Type-C接口显示器:C口高效连接与无限可能 LDR

Type-C显示器C接口的未来&#xff1a;高效连接与无限可能 随着科技的飞速发展&#xff0c;我们的日常生活和工作中对于高效、便捷的连接方式的需求日益增加。在这样的背景下&#xff0c;Type-C接口显示器凭借其卓越的性能和广泛的兼容性&#xff0c;正逐渐崭露头角&#xff0c…

RIP路由协议汇总(华为)

#交换设备 RIP路由协议汇总 一、原理概述 当网络中路由器的路由条目非常多时&#xff0c;可以通过路由汇总&#xff08;又称路由汇聚或路由聚合&#xff09;来减少路由条目数&#xff0c;加快路由收敛时间和增强网络稳定性。路由汇总的原理是&#xff0c;同一个自然网段内的不…