【算法day4】链表:应用拓展与快慢指针

题目引用


  1. 两两交换链表节点
  2. 删除链表的倒数第n个节点
  3. 链表相交
  4. 环形链表

1.两两交换链表节点


给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。
示例 1:
在这里插入图片描述
输入:head = [1,2,3,4]
输出:[2,1,4,3]
示例 2:
输入:head = []
输出:[]
示例 3:
输入:head = [1]
输出:[1]

我们先来看一下题目,这题跟昨天的翻转链表比较相似,都是控制节点指针对链表进行修改,这里呢我们先new一个虚拟头结点dummyhead来保证到最后可以找到头结点返回,然后定义一个指针curdummyhead位置,tmpcur->next位置来对其进行修改,tmp1用于标记后面节点避免剩余链表丢失。初始化定义
接着将curnext指向tmp的下一个节点
在这里插入图片描述
再将这个节点的next指向tmp节点
在这里插入图片描述
最后将tmp位置节点next指向tmp1,而cur顺势移动到tmp位置进行下一轮交换。
在这里插入图片描述
最后将dummyhead删除,本题就做完啦~
代码:

ListNode* swapPairs(ListNode* head) {
        ListNode* dummyhead=new ListNode(-1);
        dummyhead->next=head;
        ListNode* cur=dummyhead;

        while(cur->next!=nullptr&&cur->next->next!=nullptr){
            ListNode* tmp=cur->next;
            ListNode* tmp1=cur->next->next->next;
            
            cur->next=cur->next->next;
            cur->next->next=tmp;
            tmp->next=tmp1;
            cur=tmp;
        }
        ListNode* result=dummyhead->next;
        delete dummyhead;


        return result;
    }

2.删除链表的倒数第n个节点

给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
示例 1:
在这里插入图片描述
输入:head = [1,2,3,4,5], n = 2
输出:[1,2,3,5]
示例 2:
输入:head = [1], n = 1
输出:[]
示例 3:
输入:head = [1,2], n = 1
输出:[1]

首先我们分析一下题目,这道题目是可以通过遍历两遍的方式做出来的,先遍历一遍算出链表长度,再算出差值,删除节点。但是这里亦可以用快慢指针来做,并且只需要一次遍历。
首先new一个虚拟头结点dummyhead,再定义fastslow指针都指向dummyhead。再我们让fast先移动n+1个节点,再fastslow节点同时移动,直到fast为空。然后删除slow后面的节点返回链表。
为什么是n+1个节点,为什么同时移动呢?
首先回答为什么先让fast先走再同时移动,因为当fastslow同时移动时,fastslow保持了相对距离n+1,当fast移动到链表结束位置时,slow与其刚好相差n+1个节点,也就实现了一次遍历找到倒数第n个节点的期望。
那么为什么是n+1呢?因为当我们找到刚好是倒数第n个位置的节点时,我们对其进行移除操作是很困难的,所以找到倒数第n+1个刚刚好可以将第n个轻易的删除掉。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
附上代码:

ListNode* removeNthFromEnd(ListNode* head, int n) {
        if(head->next==nullptr) return nullptr;

        ListNode* dummyhead=new ListNode(0);
        dummyhead->next=head;
        ListNode* fast=dummyhead;
        ListNode* slow=dummyhead;
        while(n>=0){
            fast=fast->next;

            n--;
        }
        while(fast!=nullptr){
            fast=fast->next;
            slow=slow->next;
        }
        ListNode* tmp=slow->next;
        slow->next=slow->next->next;
        delete tmp;

        return dummyhead->next;
    }

3.链表相交

给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null 。
图示两个链表在节点 c1 开始相交:
题目数据 保证 整个链式结构中不存在环。
注意,函数返回结果后,链表必须 保持其原始结构 。
示例 1:
在这里插入图片描述

输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3
输出:Intersected at ‘8’
解释:相交节点的值为 8 (注意,如果两个链表相交则不能为 0)。
从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 [5,0,1,8,4,5]。
在 A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点。

这道题很简单,我们先通过两次遍历得到两个链表的长度,然后算出长度差,让长的链表的指针先走长度差gap步,接着两个指针同时移动一一比对,相等即返回。

ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        int lenA=0,lenB=0;
        ListNode* curA=headA;
        ListNode* curB=headB;
        while(curA){
            curA=curA->next;
            lenA++;
        }
        while(curB){
            curB=curB->next;
            lenB++;
        }
        curA=headA;curB=headB;
        if (lenB > lenA) {
            swap (lenA, lenB);
            swap (curA, curB);
        }
        // 求长度差
        int gap = lenA - lenB;
        // 让curA和curB在同一起点上(末尾位置对齐)
        while (gap--) {
            curA = curA->next;
        }
        while(curA){
            if(curA==curB){
                return curA;
            }
            curA=curA->next;
            curB=curB->next;
        }
        return NULL;
    }

4.环形链表II

给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。
不允许修改 链表。
示例 1:
在这里插入图片描述
输入:head = [3,2,0,-4], pos = 1
输出:返回索引为 1 的链表节点
解释:链表中有一个环,其尾部连接到第二个节点。

首先,我们需要判断一下是否是环形链表,定义一个fast和一个slowfast每次走两步,slow每次走一步,如果有环,那么fastslow一定会在环内的某个位置碰上,因为fastslow有速度差。
那么怎么找到环形链表的开头呢?
这就牵扯到数学问题,设头到环的入口的长度为x,入口到fastslow相遇的位置的长度为y,环剩下的长度为z,那么不难得出

2*(x+y)=n*(y+z)+x+y
x+y=n*(y+z)
x=n*(y+z)-y
x=(n-1)(y+z)+z
那么就说明了从头结点出发一个指针,fast出发一个指针,他们相遇的位置就是环形链表的入口。

那么代码如下:

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

总结

今天的题目都比较考验画图和发现规律的能力,沉下心好好学习,慢慢寻找总能找到规律。

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

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

相关文章

电商项目高级篇06-缓存

电商项目高级篇06-缓存 1、docker下启动redis2、项目整合redis3、redis改造三级分类业务 缓存 流程图: data cache.load(id);//从缓存加载数据 If(data null){ data db.load(id);//从数据库加载数据 cache.put(id,data);//保存到 cache 中 } return data;在我们…

osg、osgearth源码编译(二)

如果比较懒,也可以不看这篇文章,网上应该有很多编译好的库。也可以找我要。 本人还是建议学会编译,因为其他人电脑上编译好的,可能在你的电脑环境上,出现这样那样奇怪的问题,所以,最好还是自己能…

Kubernetes 01

MESOS:APACHE 分布式资源管理框架 2019-5 Twitter退出,转向使用Kubernetes Docker Swarm 与Docker绑定,只对Docker的资源管理框架,阿里云默认Kubernetes Kubernetes:Google 10年的容器化基础框架,borg…

中科院一区算法KO-K均值优化算法(K-means Optimizer)-附Matlab免费代码

首先,使用K-means算法在每次迭代中建立聚类区域的形心向量,然后KO提出两种移动策略,以在开发和探索能力之间建立平衡。每次迭代中探索或开发的移动策略的决定取决于一个参数,该参数将被设计为识别每个搜索代理是否在访问的区域中过…

算法复杂度

数据结构 数据结构(DataStructure)是计算机存储、组织数据的⽅式,指相互之间存在⼀种或多种特定关系的数据元素的集合。没有⼀种单⼀的数据结构对所有⽤途都有⽤,所以我们要学各式各样的数据结构,如:线性表、树、图、哈希等 算法…

用Python做数据分析环境搭建及工具使用(Jupyter)

目录 一、Anaconda下载、安装 二、Jupyter 打开 三、Jupyter 常用快捷键 3.1 创建控制台 3.2 命令行模式下的快捷键 3.3 运行模式下快捷键 3.4 代码模式和笔记模式 3.5 编写Python代码 一、Anaconda下载、安装 【最新最全】Anaconda安装python环境_anaconda配置python…

【R库包安装】R库包安装总结:conda、CRAN等

【R库包安装】R studio 安装rgdal库/BPST库 R studio 安装rgdal库解决方法 R studio 安装BPST库(github)解决方法方法1:使用devtools安装方法2:下载安装包直接在Rstudio中安装 参考 基础 R 库包的安装可参见另一博客-【R库包安装】…

前海湾地铁的腾通数码大厦背后的临时免费停车点探寻

临时免费停车点:前海湾地铁的腾通数码大厦背后的桂湾大街,目前看不仅整条桂湾大街停了​车,而且还有工地餐点。可能是这个区域还是半工地状态,故暂时还不会有​罚单的情况出现。 中建三局腾讯数码大厦项目部A栋 广东省深圳市南山…

Vue3在PC端接入萤石云监控

参考文档&#xff1a;文档概述 萤石开放平台API文档 1.安装依赖 npm i ezuikit-js 2.封装组件 src/components/PlayerVideo/index.vue <template><div id"video-container" style"width: 100%;"></div> </template> <scrip…

YOLO系列论文综述(从YOLOv1到YOLOv11)【第9篇:YOLOv7——跨尺度特征融合】

YOLOv7 1 摘要2 网络架构3 改进点4 和YOLOv4及YOLOR的对比 YOLO系列博文&#xff1a; 【第1篇&#xff1a;概述物体检测算法发展史、YOLO应用领域、评价指标和NMS】【第2篇&#xff1a;YOLO系列论文、代码和主要优缺点汇总】【第3篇&#xff1a;YOLOv1——YOLO的开山之作】【第…

Redis3——线程模型与数据结构

Redis3——线程模型与数据结构 本文讲述了redis的单线程模型和IO多线程工作原理&#xff0c;以及几个主要数据结构的实现。 1. Redis的单线程模型 redis6.0之前&#xff0c;一个redis进程只有一个io线程&#xff0c;通过reactor模式可以连接大量客户端&#xff1b;redis6.0为了…

【C++】STL容器中的比较函数对象

目录 set、map容器 priority_queue容器 在STL中涉及到以某种规则排序的容器都需要比较函数对象&#xff0c;比如&#xff1a;set、map、priority_queue这些容器内部都是依赖比较函数对象以某种规则存储数据的。STL容器中的比较函数对象可以是&#xff1a;函数指针、仿函数(函…

领养我的宠物:SpringBoot开发指南

第2章 开发环境与技术 本章节对开发宠物领养系统需要搭建的开发环境&#xff0c;还有宠物领养系统开发中使用的编程技术等进行阐述。 2.1 Java语言 Java语言是当今为止依然在编程语言行业具有生命力的常青树之一。Java语言最原始的诞生&#xff0c;不仅仅是创造者感觉C语言在编…

南京仁品耳鼻喉专科医院:12月启动公益义诊月

专业医疗资源送至“家门口”&#xff01;南京仁品耳鼻喉专科医院启动公益义诊月 随着2024年即将步入尾声&#xff0c;南京仁品耳鼻喉医院为回馈社会&#xff0c;提升公众健康福祉&#xff0c;将于12月隆重推出“三甲专家公益义诊月”活动。此次活动旨在通过汇聚众多耳鼻喉领域…

centos8:Could not resolve host: mirrorlist.centos.org

【1】错误消息&#xff1a; [rootcentos211 redis-7.0.15]# yum update CentOS Stream 8 - AppStream …

会议直击|美格智能亮相2024紫光展锐全球合作伙伴大会,融合5G+AI共拓全球市场

11月26日&#xff0c;2024紫光展锐全球合作伙伴大会在上海举办&#xff0c;作为紫光展锐年度盛会&#xff0c;吸引来自全球的众多合作伙伴和行业专家、学者共同参与。美格智能与紫光展锐竭诚合作多年&#xff0c;共同面向5G、AI和卫星通信为代表的前沿科技&#xff0c;聚焦技术…

网络安全入门之网络安全工具分享-含初期所有工具(附百度网盘链接)

网络安全基础工具 抓包工具 burpsuite 这是一款十分经典的抓包改包工具&#xff0c;在全球范围内使用十分广泛&#xff0c;并且其内置各种插件&#xff0c;具有爆破&#xff0c;自动识别验证码&#xff0c;加解密发包等多种功能 专业版破解网盘链接&#xff1a; 通过百度网…

联想Lenovo SR650服务器硬件监控指标解读

随着企业IT架构的复杂性和业务需求的增长&#xff0c;服务器的稳定运行变得至关重要。联想Lenovo SR650服务器以其高性能和稳定性&#xff0c;在各类应用场景中发挥着关键作用。为了保障服务器的稳定运行&#xff0c;监控易作为一款专业的IT基础设施监控软件&#xff0c;为联想…

Android studio 利用cmake编译和使用so文件

1.编译出so文件 1.1 创建支持c的项目 需要在sdk-tools下载ndk和cmake Android studio会自动给一个含有jni的demo&#xff0c;运行打印出 hello c&#xff1b; //这边你文件project static {System.loadLibrary("withnewest");} //声明需要调用的方法 public nativ…

【论文笔记】Frequency Domain Model Augmentation for Adversarial Attack

Abstract 对于黑盒攻击&#xff0c;替代模型与受害模型之间的差距通常较大&#xff0c;表现为较弱的攻击性能。基于对抗样本的可迁移性可以通过同时攻击不同模型来提高的观察&#xff0c;提出了利用变换图像模拟不同模型的模型增强方法。 然而&#xff0c;现有的空间域变换并没…