链表常见题型(1)

1.反转链表

1.1反转链表

      如果我们想要反转链表,那应该有head的next指针指向空,其余结点的next指针反过来,指向它的上一个结点,那我们在执行该操作的时候就需要定义变量cur(current)表示我们当前遍历到的结点,变量pre(previous)表示上一个结点,对于第一个结点来说,它的上一个结点为空,我们需要把当前的next指针指向上一个结点,但两个变量够吗?当我们修改当前结点的next指针时,它的下一个结点就丢失了,所以在修改之前还需要再定义一个变量nxt(next)记录cur的下一个结点,之后我们就可以把cur的next指针指向pre,pre=cur,cur=nxt,如此循环,当反转结束后,pre指向反转这一段的末尾,cur指向反转这一段末尾的下一个结点,所以反转结束时,cur指向NULL,如图所示

 ListNode* reverseList(ListNode* head){ListNode* nxt;ListNode* pre=NULL;ListNode* cur=head;while(cur){nxt=cur->next;cur->next=pre;pre=cur;cur=nxt;}return pre;}

 1.2反转链表||

     做这道题我们要用到上一道题的性质:当反转结束后,pre指向反转这一段的末尾,cur指向反转这一段末尾的下一个结点。所以当翻转结束后cur指向5,pre指向4,所以我们要把2指向cur,1指向pre,这样就组成了14325,我们需要记录反转这一段的上一个结点p,所以就是把p的next指向cur,p指向pre,但是当left等于1时是没有p的,所以此时我们要建立一个虚拟头结点,代码如下

ListNode* reverseBetween(ListNode* head, int left, int right) {ListNode* dummyhead=new ListNode(0,head);ListNode* p=dummyhead;for (int i = 0; i < left - 1; ++i)p = p->next;ListNode *pre = NULL, *cur = p->next;for (int i = 0; i < right - left + 1; ++i) {ListNode *nxt = cur->next;cur->next = pre; pre = cur;cur = nxt;}p->next->next = cur;p->next = pre;return dummyhead->next;}

1.3K个一组翻转链表

      这个要求我们k个结点一组进行翻转,所以我们要先求出来链表的长度,如果大于等于k时,我们要判断剩余结点的个数,小于k是无法翻转的,翻转的过程和上一题是一样的,需要注意的是我们额外要在翻转之后把p更新成下一段要翻转的链表的上一个结点,但是由于最后我们修改了p的next指针,所以我们需要在修改之前额外创建一个临时变量nxt=p->next,翻转结束后令p=nxt开始下一段循环,不断循环,最后返回dummyhead->next,代码如下:

 ListNode* reverseKGroup(ListNode* head, int k) {ListNode* head1=head;int len=0;while(head1){len++;head1=head1->next;}ListNode* dummyhead=new ListNode(0,head);ListNode* p=dummyhead;ListNode *pre = NULL, *cur = p->next;for (; len>=k;len-=k ) {for(int i=0;i<k;i++){ListNode *nxt = cur->next;cur->next = pre; pre = cur;cur = nxt;}ListNode* nxt=p->next;p->next->next = cur;p->next = pre;p=nxt;
}return dummyhead->next;}

2.链表删除

    我们要想删除链表的某个结点,需要利用上一个结点的next指针指向删除结点的下一个结点

2.1删除链表中的节点

 

     之前我们在基础数据结构讲过如何删除一个结点,但这个它不给我头结点,我怎么删除啊,这题就很秒,它说node不是链表的最后一个结点,也就是说我们可以把node结点的下一个结点的值复制过来,然后删除下一个结点,这可太妙了!

void deleteNode(ListNode* node) {node->val=node->next->val;node->next=node->next->next;
}

2.2 删除链表的倒数第N个结点

     第一种做法就是遍历求出链表长度,这样我们就知道要删除的倒数第N个结点是正数的第几个了,我们再遍历到这个结点的上一个结点执行删除操作,同时因为n可能等于链表长度,所以我们需要建立虚拟头结点,这样就OK了。

    第二种做法是快慢指针,我们需要找到倒数第N+1个结点,初始化右指针指向虚拟头结点,先让右指针走N步,然后初始化左指针指向虚拟头结点,左右指针一起向右移动,这样两个指针的距离始终为N,当右指针走向倒数第一个结点,左指针就恰好走到了倒数第N+1个结点,这时候就可以执行删除操作了!

ListNode* removeNthFromEnd(ListNode* head, int n) {ListNode* dummyhead=new ListNode(0);dummyhead->next=head;ListNode* slow=dummyhead;ListNode* fast=dummyhead;while(n--&&fast!=NULL){fast=fast->next;}while(fast->next!=NULL){slow=slow->next;fast=fast->next;}slow->next=slow->next->next;return dummyhead->next;}

2.3删除排序链表中的重复元素

     这个题还是比较简单的,首先并不需要虚拟头结点,因为就算头结点的值和下一个结点的值相等,也会保留头结点,我们只需要遍历链表,如果cur的下一个结点的val值和cur的val值相等,我们就删除cur的下一个结点,需要注意的是循环条件是cur->next,当cur遍历到最后一个结点时,cur的下一个结点就不存在是NULL,此时应该退出循环,如果是cur则会继续进入循环造成NULL指针的解引用,会报错

    ListNode* deleteDuplicates(ListNode* head) {if(head==NULL)return NULL;ListNode* cur=head;while(cur->next){if(cur->next->val==cur->val){cur->next=cur->next->next;}else{cur=cur->next;}}return head;}

 2.4 删除排序链表中的重复元素||

     首先这个题需要建立虚拟头结点,因为如果开头就有几个重复的结点,那么头结点会被删除,所以我们先创建一个虚拟头结点,然后初始化cur指针指向虚拟头结点,然后遍历链表,每次遍历时,先取出cur的next的值val,如果cur的next的next的值和val相等,再进入循环判断cur的next的值是否等于val,相等就删除,否则移动到下一个结点,最后返回头结点

 ListNode* deleteDuplicates(ListNode* head) {ListNode* dummyhead=new ListNode(0);dummyhead->next=head;ListNode* cur=dummyhead;while(cur->next&&cur->next->next){int val=cur->next->val;if(cur->next->next->val==val){while(cur->next&&cur->next->val==val){cur->next=cur->next->next;}}else{cur=cur->next;}}return dummyhead->next;}

 

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

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

相关文章

【后台报错】插入时sql报错,varchar撑爆

后台的一个报错。按照正常的需要复现&#xff0c;或者查一下日志。但是凭借多年经验和大胆猜测&#xff0c;以及对自己代码要自信 引用一下文章 目测7*15 105项。每个id有9个数字加上分隔符刚好十个。大概就是超过了定义的一千的varchar长度。直接改数据库就好了。 简单粗暴…

【金猿CIO展】乖宝宠物CIO王天刚:以数据为核心,转变业务模式

‍ 王天刚 本文由乖宝宠物CIO王天刚撰写并投递参与“数据猿年度金猿策划活动——2023大数据产业年度趋势人物榜单及奖项”评选。 大数据产业创新服务媒体 ——聚焦数据 改变商业 随着社会经济的快速发展&#xff0c;“宠物经济”悄然崛起&#xff0c;宠物在家中的角色地位有时…

c语言:计算1+2+3……+n的和|练习题

一、题目 输入一个数n&#xff0c;计算123……n的和 二、代码截图【带注释】 三、源代码【带注释】 #include int main() { int num0; printf("请输入要运算的数:"); scanf("%d",&num); sumResult(num);//相加结果函数 } //计算打印…

【智能家电】东胜物联离在线语音方案为厨电企业赋能,实现厨房智能化控制

近年来&#xff0c;我国厨电市场蓬勃发展。据行业统计数据显示&#xff0c;至今年6月&#xff0c;市场规模已达356亿元&#xff0c;同比增长8.8%。随着数字科技、物联网和人工智能的兴起&#xff0c;厨电产品正在朝着更智能、多功能化的方向迅速发展。 为此厨电厂商正在积极布…

EarMaster Pro 7 简体中文破解版 v7.2.0.42 电脑版

软件介绍 EarMaster破解版一款功能强大的专业级别多媒体音乐教育学习软件&#xff0c;EarMaster破解版提供了大量音乐相关的学习内容&#xff0c;用户在这里可以学习基础的和弦、音阶、节奏&#xff0c;也可以提升自己的音感&#xff0c;如果基础已经很扎实了&#xff0c;还可…

加拿大 ANUSPLIN 网格气候数据集

ANUSPLIN 网格气候数据集 加拿大 ANUSPLIN 网格气候数据集是使用澳大利亚国立大学样条 (ANUSPLIN) 模型生成的基于站点的插值数据集。它由加拿大农业和农业食品部生产&#xff0c;覆盖加拿大全境。该数据集提供 1950 年至 2015 年期间每日和每月时间步长的最高气温、最低气温和…

OpenFeign 万字教程详解

OpenFeign 万字教程详解 目录 一、概述 1.1.OpenFeign是什么&#xff1f;1.2.OpenFeign能干什么1.3.OpenFeign和Feign的区别1.4.FeignClient 二、OpenFeign使用 2.1.OpenFeign 常规远程调用2.2.OpenFeign 微服务使用步骤2.3.OpenFeign 超时控制2.4.OpenFeign 日志打印2.5.O…

【小黑嵌入式系统第十二课】μC/OS-III程序设计基础(二)——系统函数使用场合、时间管理、临界区管理、使用规则、互斥信号量

上一课&#xff1a; 【小黑嵌入式系统第十一课】μC/OS-III程序设计基础&#xff08;一&#xff09;——任务设计、任务管理&#xff08;创建&基本状态&内部任务&#xff09;、任务调度、系统函数 文章目录 一、系统函数使用场合1.1 时间管理1.1.1 控制任务的执行周期1…

CSS新手入门笔记整理:CSS3弹性盒模型

特点 子元素宽度之和小于父元素宽度&#xff0c;所有子元素最终的宽度就是原来定义的宽度。子元素宽度之和大于父元素宽度&#xff0c;子元素会按比例来划分宽度。在使用弹性盒子模型之前&#xff0c;必须为父元素定义“display:flex;”或“display:inline-flex;”。 弹性盒子…

一款基于.NET Core的快速开发框架、支持多种前端UI、内置代码生成器

前言 经常看到有小伙伴在技术群里问有没有什么好用且快速的开发框架推荐的&#xff0c;今天就给大家分享一款基于MIT License协议开源、免费的.NET Core快速开发框架、支持多种前端UI、内置代码生成器、一款高效开发的利器&#xff1a;WalkingTec.Mvvm框架&#xff08;简称WTM…

CyclicBarrier实战应用——实现异步多线程业务处理,异常情况回滚全部子线程

&#x1f60a; 作者&#xff1a; 一恍过去 &#x1f496; 主页&#xff1a; https://blog.csdn.net/zhuocailing3390 &#x1f38a; 社区&#xff1a; Java技术栈交流 &#x1f389; 主题&#xff1a; CyclicBarrier实战应用——实现异步多线程业务处理&#xff0c;异常情况…

Linux笔记本电脑投屏到电视,用网页浏览器就能投屏到电视!

Linux系统的电脑如果要投屏到安卓电视屏幕上&#xff0c;可以使用投屏工具AirDroid Cast的网页版和TV版一起实现。 首先&#xff0c;在Linux系统的电脑里用chrome浏览器或edge浏览器打开网址webcast.airdroid.com。这个网址就是AirDroid Cast的网页版。你可以看到中间白色框框的…

Canal使用详解

Canal介绍 Canal是阿里巴巴开发的MySQL binlog增量订阅&消费组件&#xff0c;Canal是基于MySQL二进制日志的高性能数据同步系统。在阿里巴巴集团中被广泛使用&#xff0c;以提供可靠的低延迟增量数据管道。Canal Server能够解析MySQL Binlog并订阅数据更改&#xff0c;而C…

cilium原理之ebpf尾调用与trace

背景 在深入剖析cilium原理之前&#xff0c;有两个关于epbf的基础内容需要先详细介绍一下&#xff1a; 1. ebpf尾调用 尾调用类似于程序之间的相互跳转&#xff0c;但它的功能更加强大。 2. trace 虽然之前使用trace_printk输出日志&#xff0c;但这个函数不能多用&#x…

使用StableDiffusion进行图片Inpainting原理

论文链接&#xff1a;RePaint: Inpainting using Denoising Diffusion Probabilistic Models代码链接&#xff1a;RePaint Inpainting任务是指在任意一个二进制的掩码指定的图片区域上重新生成新的内容&#xff0c;且新生成的内容需要和周围内容保持协调。当前SOTA模型用单一类…

高级算法设计与分析(四) -- 贪心算法

系列文章目录 高级算法设计与分析&#xff08;一&#xff09; -- 算法引论 高级算法设计与分析&#xff08;二&#xff09; -- 递归与分治策略 高级算法设计与分析&#xff08;三&#xff09; -- 动态规划 高级算法设计与分析&#xff08;四&#xff09; -- 贪心算法 高级…

FATFS文件系统

文件系统是为了存储和管理数据&#xff0c;而在存储设备上建立的一种组织结构。 Windows常用的文件系统&#xff1a; 1、FAT12 2、FAT16 3、FAT32 4、exFAT 5、NTFS FAT&#xff1a;File Alloction Table 文件分配表 在小型的嵌入式存储设备大多…

Ubuntu 常用命令之 ping 命令用法介绍

&#x1f4d1;Linux/Ubuntu 常用命令归类整理 ping命令是一种网络诊断工具&#xff0c;用于测试主机之间网络的连通性。它发送ICMP Echo Request消息到指定的网络主机&#xff0c;并等待接收ICMP Echo Reply。通过这种方式&#xff0c;我们可以知道两台主机之间的网络是否畅通…

pycharm修改项目文件夹名称

目录 1 修改项目文件夹名称 2 修改代码中的项目名称 1 修改项目文件夹名称 选中项目文件夹&#xff0c;右键&#xff0c;选择refactor-rename。 选择rename project&#xff1a; 然后输入新的项目名称。 此时进入资源管理器&#xff0c;修改项目文件夹的名字&#xff0c;完成…

IntelliJ IDEA 2023.3 新功能介绍

IntelliJ IDEA 2023.3 在众多领域进行了全面的改进&#xff0c;引入了许多令人期待的功能和增强体验。以下是该版本的一些关键亮点&#xff1a; IntelliJ IDEA mac版下载 macappbox.com/a/intellij-idea-for-mac.html 1. AI Assistant 的全面推出 IntelliJ IDEA 2023.3 中&am…