算法: 双指针

题目:环形链表

题目讲解:

判断环

要判断链表是否有环,可以使用快慢指针的方法。快指针每次走两步,慢指针每次走一步。如果链表有环,快慢指针最终会相遇;如果没有环,快指针会先到达链表末尾。

为什么快指针走两步,慢指针走一步?因为这样快指针会更快进入环,并在环中追上慢指针。具体来说,当快指针进入环后,它将在环中不断接近慢指针,最终相遇。即使快指针在环中比慢指针快,它们也不会永远错过,而是必然会在某一时刻相遇。

这个相遇的原因是因为在每一次循环中,快指针都比慢指针多走一步,这样慢指针总会缩小它与快指针之间的距离,直至两者相遇。

如果操场是一个环形的(即链表有环),那么即使快跑者一开始远远超过慢跑者,由于他们在同一条跑道上不断绕圈,快跑者最终一定会追上慢跑者。这是因为在每一圈中,快跑者都会比慢跑者多跑一圈的距离,最终两人会在某个点相遇。

代码实现:

class Solution 
{
public:bool hasCycle(ListNode *head) {//判断空链表及单节点if(head == nullptr || head->next == nullptr){return false;}ListNode* fast = head->next;ListNode* slow = head;while(fast != nullptr && fast->next != nullptr){fast = fast->next->next;slow = slow->next;if(fast == slow){return true;} }return false;}
};

注意事项:

在处理链表时,必须仔细考虑 while 循环的判断条件。如果链表不是环形的,快指针每次移动两步可能会最终指向空引用,导致野指针问题。为了避免这种情况,你需要提前检查快指针的下一个节点是否为空。使用 && 运算符可以确保两个条件都为真,这样可以防止当链表只有两个节点时发生错误——在这种情况下执行 fast = fast->next->next; 会导致野指针。

关于快指针最初指向第一个节点而慢指针指向空的做法,在这里并不适用。如果 slow 为空,执行 slow = slow->next; 会导致空指针引用错误。因此,必须根据具体问题定制你的方法,而不是盲目套用模式。

题目:环形链表||

题目讲解:

找环入口

数学解释

假设链表中从头到环入口点的距离是 a

环的长度是 b + c(其中 b 是从环入口点到 slowfast 相遇点的距离

c 是从相遇点再回到入口点的距离。

相遇时slow走过的路程是 a + b

相遇时fast走过的路程是 a + (b+ c) + b

又因为fast走的路程是slow的两倍所以 2(a + b) ==  a + (b+ c) + b ->  a = c

所以头到入口的距离就等于相遇点到入口的距离,这样的话让它们从头和快慢指针相遇的地点一起出发,等什么时候它们相遇那就什么时候遇到入口。

快慢指针相遇的理解

fast 指针比 slow 指针更早进入环,并且在环内移动得更快。当 slow 进入环时,fast 就开始追赶它。由于 fast 每次走两步,而 slow 只走一步,这就好像 fast 在不断地逼近一个“静止”的目标。你可以把这情况类比为 slow 不动,而 fast 每次向前移动一步。在这种情况下,fast 会很快追上 slow

因此,slow 并不需要走完整个环就会被 fast 追上。相遇是必然的,而 slow 没走完一整圈就和 fast 相遇的情况,正是因为 fast 在追击 slow 的过程中缩短了它们之间的距离。

代码实现:

class Solution 
{
public:ListNode *detectCycle(ListNode *head) {if(head == nullptr || head->next == nullptr){return nullptr;}ListNode* fast = head;ListNode* slow = head;ListNode* Ptr = head;while(fast != nullptr && fast->next != nullptr){fast = fast->next->next;slow = slow->next;if(fast == slow){while(Ptr != fast){Ptr = Ptr->next;fast = fast->next;}return Ptr;}}return nullptr;}
};

题目:寻找重复数

题目讲解:

数组该怎样链表化?

你是否想过,数组中的每个元素其实可以看作链表中的一个节点?那么,这些节点该如何指向彼此呢?链表中的指向并不是随意的,它靠什么来决定呢?

答案就在数组的下标和元素之间的关系。下标永远是固定的,从 0 开始不变,而真正“变动”的是数组中的元素。每个元素的值决定了它指向的下一个位置。比如,数组的第一个元素是 1,它就会指向下标为 1 的位置。如果下标 1 的元素是 3,那么它再指向下标 3 的位置。如此循环下去,直到某个节点被指向两次,这就意味着找到了重复的数字。这样,你就把数组成功“链表化”了,利用这个方法轻松找出数组中的重复元素。

代码实现:

class Solution 
{
public:int findDuplicate(vector<int>& nums) {int fast = 0;int slow = 0;do{slow = nums[slow];fast = nums[nums[fast]]; // 走两步}while(slow != fast);int tmp = 0;while(tmp != fast){tmp = nums[tmp];fast = nums[fast];}return tmp;}
};

题目:快乐水

题目讲解:

这个题目其实和之前的三道题思路类似。题目给出了两种情况:第一种是计算结果为 1,然后进入无限循环,循环的数字全是 1;第二种是永远算不出 1,进入一个与 1 无关的数字循环。这个循环可以被看作一个“环”,要么全是 1,要么是其他数。我们需要找到这个“环”的入口,也就是第一个 1 或者与 1 无关的数。

其实,这就是在找环的入口,完全可以用快慢指针来解决。快慢指针的核心思想是,一个走得快,一个走得慢,只要能满足这个条件,就可以称为快慢指针。在这里,我们让慢指针每次变化一次,快指针每次变化两次。如果它们相遇且值为 1,就返回 true,否则返回 false

代码实现:

class Solution 
{
public:int qwe(int number){int sum = 0;int tmp = 0;while(number){tmp = number % 10;sum += tmp * tmp;number = number / 10;}return sum;}bool isHappy(int n) {int slow = n;int fast = n;do{slow = qwe(slow);fast = qwe(fast);fast = qwe(fast);}while(slow != fast);if(slow == 1){return true;}return false;}
};

题目:删除链表的倒数第N个元素

题目讲解:

这道题可以先让快指针走n步然后再让慢指针和快指针一同走那这样快指针走到结尾那慢指针也就刚好移动到目标位置的前一个。

代码实现:

class Solution 
{
public:ListNode* removeNthFromEnd(ListNode* head, int n) {ListNode* dummyHead = new ListNode(0 , head);dummyHead->next = head;ListNode* fast = dummyHead;ListNode* slow = dummyHead;for (int i = 0; i <= n; ++i) {fast = fast->next;}while(fast){fast = fast->next;slow = slow->next;}slow->next = slow->next->next;return dummyHead->next;}
};

这里定义哨兵位(虚拟头节点)的作用:
 

为什么要用虚拟头节点(哨兵位)?

  • 当我们需要删除链表中的某个节点时,通常需要访问待删除节点的前一个节点,因为删除操作涉及到将前一个节点的 next 指针重新指向待删除节点的下一个节点。

2. 删除头节点的特殊情况

  • 如果没有虚拟头节点,要删除头节点会比较麻烦,因为头节点前面没有其他节点,无法轻易访问它的前一个节点。因此,删除头节点通常需要特别处理,直接返回第二个节点来实现删除。

3. 虚拟头节点解决了什么问题?

  • 引入虚拟头节点后,即使是删除头节点的操作,我们也可以按照统一的方式处理。虚拟头节点的 next 指向实际的头节点,这样我们就能在删除任何节点时,不需要再为删除头节点编写额外的特殊逻辑了。

4. 总结

  • 统一的删除逻辑:有了虚拟头节点后,删除头节点就变得和删除其他节点一样,不需要再单独处理特殊情况。
  • 代码简洁性:使用虚拟头节点让代码更简洁,因为所有节点的删除操作都可以通过相同的逻辑来处理,无需特别关注链表的第一个节点。

题目:链表的中间节点

题目讲解:

这题比较easy,所以我就贴代码算了。

代码实现:

class Solution 
{
public:ListNode* middleNode(ListNode* head) {ListNode* fast = head;ListNode* slow = head;while(fast && fast->next){fast = fast->next->next;slow = slow->next;}return slow;}
};

题目:回文链表

题目讲解:

判断回文链表我们可以先利用快慢指针找到前部分的尾部然后然后再去反转后部分链表判断,然后再去判断它们的val是否一摸一样,我们唯一要注意的就是反转链表,

代码实现:

class Solution 
{
public:
//反转中间节点后的数据
ListNode* reverse(ListNode* Newhead)
{
ListNode* PPfast = Newhead;
ListNode* PPslow = nullptr;while(PPfast){ListNode* next = PPfast->next;PPfast->next = PPslow;PPslow = PPfast;PPfast = next;}Newhead = PPslow;return Newhead;
}bool isPalindrome(ListNode* head) {ListNode* dummyHead = new ListNode (0 , head);dummyHead->next = head;ListNode* fast = head;ListNode* slow = head;// while(fast && fast->next){slow = slow->next;fast = fast->next->next;}fast = reverse(slow);slow = head;while(fast && slow){if(fast->val != slow->val){return false;}fast = fast->next;slow = slow->next;}return true;}
};

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

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

相关文章

MySQL:简述对事务的认识

浅谈对Spring事务的认识&#xff1a;https://xiaoer.blog.csdn.net/article/details/80849971 一、事务的特性 事务是数据库永恒不变的话题&#xff0c; ACID&#xff1a;原子性&#xff0c;一致性&#xff0c;隔离性&#xff0c;持久性。 &#xff08;1&#xff09;原子性&am…

基于麒麟信安操作系统的光伏发电功率预测系统完成大规模部署建设

麒麟信安操作系统&#xff0c;作为行业数智化建设的安全根基&#xff0c;为电力业务系统提供了稳定可靠的底层平台&#xff0c;在全球能源结构转型大潮中扮演着至关重要的角色。某光伏电站项目中&#xff0c;基于麒麟信安操作系统的光伏发电功率预测系统完成大规模部署建设&…

手机游玩植物大战僵尸杂交版V2.3.7最新版教程(文章末尾免费直接下载链接)

最新版植物大战僵尸杂交版V2.3.7手机游玩教程 【V2.3.7全面升级】植物大战僵尸杂交版&#xff1a;跨平台终极安装指南 - 苹果、安卓、电脑、电视兼容&#xff0c;界面革新&#xff0c;16卡槽扩展&#xff0c;高分辨率支持&#xff0c;BUG修复&#xff0c;畅享游戏乐趣 前言 …

Java Web —— 第九天(事务)

事务管理 & AOP 事务回顾 概念 事务 是一组操作的集合&#xff0c;它是一个不可分割的工作单位&#xff0c;这些操作 要么同时成功&#xff0c;要么同时失败 操作 开启事务(一组操作开始前&#xff0c;开启事务): start transaction / begin 提交事务(这组操作全部成功…

Word文档被锁定无法编辑怎么办?一键快速移除Word编辑限制

有没有遇到这种情况&#xff1f;打开Word文档后&#xff0c;准备对Word软件进行文档的编辑时&#xff0c;发现文档有部分内容无法进行编辑了&#xff0c;不知道怎么回事&#xff0c;其实这是因为无法编辑区域被锁定了&#xff0c;所以无法进行编辑&#xff0c;那么应该怎么解除…

Scrapy 分布式爬虫框架 Scrapy-Redis

github官网代码示例&#xff1a;https://github.com/rmax/scrapy-redis/blob/master/example-project/example/spiders/myspider_redis.py 什么是 Scrapy-Redis Scrapy-Redis 是一个基于 Scrapy 的扩展&#xff0c;用于实现分布式爬虫。它利用 Redis 作为分布式队列来共享待爬…

【Qt窗口】—— 浮动窗口

目录 1.1 浮动窗口的创建 1.2 设置停靠的位置 1.3 示例小结 在Qt中&#xff0c;浮动窗口也称之为铆接部件&#xff0c;俗称为子窗口&#xff0c;浮动窗口是通过QDockWidget类来实现浮动的功能。浮动窗口⼀般是位于核⼼部件的周围&#xff0c;可以有多个。 1.1 浮动窗口的…

CAD如何批量输出PDF?介绍了三种方式

CAD如何批量输出PDF&#xff1f;在工程设计、建筑制图以及产品设计等领域&#xff0c;CAD软件是不可或缺的工具。随着项目规模的扩大&#xff0c;如何将CAD图纸批量转换成PDF格式以便分享、打印或存档&#xff0c;成为了许多设计师面临的常见问题。下文将介绍三种高效的方法&am…

springboot3.x入门系列【5】支持unix sock 套接字服务

目录 一、简介 二、springBoot3.x 套接字的支持 1. 环境要求 2. springboot内置tomcat 2.1 支持unix 设置 unixDomainSocketPath 2.2 windows 下unix服务测试 3. springboot外置tomcat 3.1 tomcat 配置unix socket 套接字 3.2 启动tomcat 服务 3.3 nginx 支持unix…

SLAM学习笔记

从《slam十四讲开始》 slam十四讲推荐的其他书籍 《概率机器人》&#xff08;Probabilistic robotics &#xff09; 《计算机视觉中的多视图几何》&#xff08;Multiple View Geometry in Computer Vision &#xff09; 《机器人学中的状态估计》&#xff08;State Estimation…

操作系统

操作系统是控制和管理计算机硬件和软件资源。 管理和控制电脑系统软硬件资源的软件叫作操作系统&#xff0c;操作系统是最基本、最重要的系统软件&#xff0c;由一组控制计算机系统并对计算机系统进行管理的程序组成&#xff0c;是用户与计算机硬件系统的接口&#xff0c;并为用…

VMware网络模式

一.VMware虚拟网络 VMware支持共创建20个虚拟网络&#xff0c;相当于现实生活的交换机&#xff0c;名称vmnet0---vmnet19 物理机用虚拟网卡和对应的虚拟网络中的虚拟机通信。 VMnet1和VMnet8这两个虚拟网卡的作用是保证windows和虚拟机可以正常通信。VMware Workstation Pro这…

python-读写Excel:xlwings库操作

几种操作Excel的python库对比 安装:pip install xlwings 目录 APP实例化对象 工作薄对象 创建工作薄 打开工作薄 工作薄属性 工作表对象 新增工作表 复制表 获取工作表对象 工作表属性 删除和清除表数据及表格式 工作表行高列宽(自动调整) 单元格对象 获取单元…

秋冬春夏,纪念在CSDN的第365天

目录 时光 收获 工作 生活 憧憬 时光 再次收到创作纪念日的消息时&#xff0c;已在CSDN创作和度过了一年的时光。创作&#xff0c;成了自己的第二工作空间&#xff0c;成为了日常的一种习惯。 每当看到第1篇文章的提醒消息&#xff0c;都会想起当时创作的初衷和情景。是一…

在手机在线预览3D模型,是如何实现的?

在手机在线预览3D模型&#xff0c;主要依赖于几个关键技术和步骤来实现。以下是一个概括性的流程&#xff1a; 一、模型上传 选择平台&#xff1a;首先&#xff0c;用户需要选择一个支持3D模型在线预览的平台&#xff0c;如51建模网、Sketchfab等。这些平台通常提供用户友好的…

五分钟本地部署Uptime Kuma运维监控结合内网穿透实现远程访问

文章目录 前言**主要功能**一、前期准备本教程环境为&#xff1a;Centos7&#xff0c;可以跑Docker的系统都可以使用本教程安装。本教程使用Docker部署服务&#xff0c;如何安装Docker详见&#xff1a; 二、Docker部署Uptime Kuma三、实现公网查看网站监控四、使用固定公网地址…

Kafka的生产者和消费者机制

目录 1.基础的客户端 1.1消息发送者的主流程 1.2消息消费者主流程 2.客户端工作机制 2.1消费者分组消费机制 2.2生产者拦截器机制 2.3消息序列化机制 2.4消息分区路由机制 2.5生产者消息缓存机制 2.6发送应答机制 2.7生产者消息幂等性 (1)生产者消息幂等性介绍 (2…

XDMA原理

目录 1. BAR Space Map2. PCIe to AXI Lite Master2.1. BAR Address to AXI Address 3. PCIe to DMA Bypass4. AXI4 Memory Mapped4.1. Register Space 5. AXI Lite Slave Configuration Interface6. MSI/MSI-X Interrupt6.1. Interrupts Configuration6.2. IRQ Module 7. IP E…

Gitlab迁移到新的服务器后点击Integrations报500错误的解决方法

目录 一、问题描述二、解决方法1.方法12.方法2(1)备份 /etc/gitlab/gitlab-secrets.json(2)进入数据库(3)查看 Project ID(4)查找 hook ID 并删除(5)申请访问令牌并执行 api 删除操作一、问题描述 Gitlab迁移到新的服务器后点击Integrations报500错误: 查后台日志…

前后端开发学习路线 囊括Dubbo、Elasticsearch等

以下都是博主本人看过后给出的推荐。 文章目录 前端入门Web开发基础&#xff08;HTML、CSS、JS&#xff09;写项目前置&#xff08;AJAX、Vue等&#xff09;开始写项目&#xff08;Vue、Uniapp&#xff09;重点Future 入门Java后端基础部分&#xff08;Java、MySQL&#xff09;…