数据结构——单链表OJ题(上)

目录

一、移除链表元素

1.思路

2.注意

3.解题

二、反转链表

思路1:三指针翻转法

(1)注意

(2)解题

思路2:头插法

(1)注意

(2)解题

三、链表的中间结点

思路1:快慢指针法

(1)注意

(2)解题 

思路2:两次遍历法

(1)注意

(2)解题

四、返回倒数第k个结点

1.思路:快慢指针法

2.注意

3.解题

五、合并两个有序链表

1.思路

2.注意

3.解题

六、链表分割

1.思路

2.注意

3.解题

七、写在最后

 


一、移除链表元素

1.思路

创建一个新链表,用指针pcur遍历原链表,对每个结点的数据进行判断,如果等于val则不做处理,如果不相等则尾插到新链表中。

2.注意

(1)原链表可能为空,那么返回NULL;

(2)最后记得将newTail指向NULL,在此之前需要判断newTail不能为空,因为如果为空,不存在newTail->next。

3.解题

typedef struct ListNode ListNode;
struct ListNode*removeElements(ListNode* head , int val)
{if(head == NULL)//传入的该链表可能为空{return NULL;}//创建一个新链表ListNode* newHead = NULL;ListNode* newTail = NULL;//创建一个遍历该链表的指针ListNode* pcur = head;while(pcur){if(pcur->val != val){如果不等于val,尾插到新链表中if(newHead == NULL){newHead = newTail = pcur;}else{newTail->next = pcur;newTail = newTail->next;}}pcur = pcur->next;}//将尾结点指向NULLif(newTail){newTail->next = NULL;}return newHead;
}

二、反转链表

思路1:三指针翻转法

创建三个指针n1,n2,n3分别指向NULL、head和head->next,改变指向,将n2指向n1,进行循环遍历原链表。

(1)注意

①原链表可能为空,那么返回NULL;

②n1为反转链表的头结点。

(2)解题

typedef struct ListNode ListNode;
ListNode* reverseList(ListNode* head)
{if(head == NULL){return NULL;}ListNode *n1,*n2,*n3;n1 = NULL;n2 = head;n3 = head->next;while(n2){n2->next = n1;n1 = n2;n2 = n3;if(n3){n3 = n3->next;}}return n1;
}

思路2:头插法

创建新链表,通过pcur遍历原链表,将数据头插到原链表中,得到反转链表。

(1)注意

①创建新指针保存pcur的下一个结点,否则pcur无法找到原位置。

(2)解题

typedef struct ListNode ListNode;
struct ListNode* reverseList(struct ListNode* head)
{//新链表ListNode* newhead = NULL;ListNode* pcur = head;while(pcur){//保存当前结点的下一个结点ListNode* next = pcur->next;//头插新结点pcur->next = newhead;//更新头结点newhead = pcur;//移动到下一个结点pcur = next;}return newhead;
}

三、链表的中间结点

思路1:快慢指针法

初始时,快指针和慢指针都指向头结点。快指针一次经过两个结点,慢指针一次经过一个节点,当快指针走到链表结尾时,慢指针指向链表中间。

(1)注意

①分别分析一下链表长度为奇数和偶数时的情况(具体在代码中);

②最后返回指向链表中间的指针slow。

(2)解题 

typedef struct ListNode ListNode;
ListNode* middleNode(ListNode* head)
{ListNode* fast = head;ListNode* slow = head;while(fast && fast->next)//由于fast->next要取next,因此不能为空//且不能交换顺序:否则链表长度为偶数的情况不能实现{fast = fast->next->next;slow = slow->next;}return slow;
}

思路2:两次遍历法

第一次遍历得到链表的长度len,由此得到半个长度mid,第二次遍历得到中间结点。

(1)注意

①mid为len/2+1(len为int类型);

②在第二个while循环中,pcur初始为head,每进行一次循环pcur就指向下一个结点。因此,当mid写为len/2,那么在第二次循环中就顺利可实现。

(2)解题

typedef struct ListNode ListNode;
struct ListNode* middleNode(struct ListNode* head) 
{ListNode* pcur = head;int len = 0;//遍历得到链表的长度lenwhile(pcur){len++;pcur = pcur->next;}int mid = len / 2 ;//让pcur遍历链表,得到中间结点pcur = head;while(mid--){pcur = pcur->next;}return pcur;
}

四、返回倒数第k个结点

1.思路:快慢指针法

初始时,快指针和慢指针都指向头结点。快指针先走k步,然后快、慢指针同时走,当快指针走到链表末尾时,慢指针走到倒数第k个结点。

2.注意

①返回的是倒数第k个结点保存的数据,而非指针;

②若k大于链表长度,fast会为空,此时返回NULL。

3.解题

typedef struct ListNode ListNode;
int kthToLast(struct ListNode* head, int k)
{ListNode* fast = head;ListNode* slow = head;while(k--){if(fast){fast = fast->next;}else {return NULL;}}while(fast){fast = fast->next;slow = slow->next;}return slow->val;
}

五、合并两个有序链表

1.思路

创建两个指针分别遍历两个链表,比较两个指针指向结点存储的数据,创建新链表,将小的数据存储在新链表中。

2.注意

①使用malloc创建非空链表,在尾插数据时不再需要判断newHead是否为NULL,避免代码冗余;

②当n1和n2其中一个为空会跳出循环,说明遍历完成。此时需要将另外一个尾插到新链表中。

③不必再令newTail指向空,因为此时尾结点不是newTail,而是后续尾插的n1或n2。

3.解题

typedef struct ListNode ListNode;
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2)
{if(list1 == NULL){return list2;}if(list2 == NULL){return list1;}//创建新链表ListNode* newHead, *newTail;newHead = newTail = (ListNode*)malloc(sizeof(ListNode));ListNode* n1 = list1;ListNode* n2 = list2;while(n1 && n2){if(n1->val < n2->val){newTail->next = n1;newTail = newTail->next;n1 = n1->next;}else{newTail->next = n2;newTail = newTail->next;n2 = n2->next;}}if(n1){newTail->next = n1;}if(n2){newTail->next = n2;}ListNode* ret = newHead->next;free(newHead);newHead = NULL;return ret;
}

六、链表分割

1.思路

创建两个新链表(大于x和小于x的分别存储在两个链表中),用pcur遍历原链表,最后将大链表尾插在小链表后。

2.注意

①使用malloc创建两个非空链表,分别存储大于和小于x的数据。

3.解题

typedef struct ListNode ListNode;
ListNode* partition(ListNode* pHead, int x) {//大链表ListNode* greaterHead, *greaterTail;greaterHead = greaterTail = (ListNode*)malloc(sizeof(ListNode));//小链表ListNode* lessHead,*lessTail;lessHead = lessTail = (ListNode*)malloc(sizeof(ListNode));ListNode* pcur = pHead;while(pcur){if(pcur->val < x){lessTail->next = pcur;lessTail = lessTail->next;}else {greaterTail->next = pcur;greaterTail = greaterTail->next;}pcur = pcur->next;}lessTail->next = greaterHead->next;greaterTail->next = NULL;ListNode* ret = lessHead->next;free(lessHead);free(greaterHead);lessHead = greaterHead = NULL;return ret;}

七、写在最后

一起加油,敬请期待“单链表OJ题(下)”~

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

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

相关文章

AWS 中国区同账号0etl integration配置步骤

中国区的AWS支持0etl integration已经一段时间了&#xff0c;目前北京区和宁夏区均支持。中文翻译为零ETL集成。 当前支持的引擎是Aurora MySQL数据托管式导出到Redshift. Global区域支持Aurora PostgreSQL. 中国区后续也会陆续出现此功能的。 功能介绍文档&#xff1a; 【1…

正则表达式的匹配模式有那些?

1、不区分大小写模式&#xff08;IgnoreCase&#xff09;&#xff1a; 在匹配文本字符串时&#xff0c;不区分文本字符串中的大小写。 在不同编程语言中&#xff0c;此模式的指定方式可能有所不同。例如&#xff0c;在Python中&#xff0c;可以使用常量re.I或re.IGNORECASE&a…

try-catch-finally 捕获异常不在catch里抛出;循环遍历对象生成任务,捕获异常对象不抛出,不影响其他正常对象生成任务

场景&#xff1a;一个模板绑定多个对象&#xff0c;要对每个对象生成任务。捕获生成任务过程中的异常&#xff0c;但是不抛出&#xff0c;只是用日志记录。这样做目的&#xff1a;循环遍历对象生成任务时&#xff0c;异常对象数据生成任务时发生异常只是导致自己生成任务失败&a…

Mac应用快速启动器:Alfred 5 for Mac 激活版

Alfred 5 是一款专为 macOS 系统设计的效率提升工具。这款软件以其快速启动和高效操作功能著称&#xff0c;通过使用快捷键来呼出输入界面&#xff0c;用户可以快速完成各种任务。 最新版本 Alfred 5.5 引入了一些新功能。其中包括整合了 ChatGPT 和 DALL-E&#xff0c;这意味…

YOLOv8不同位置引入RepVGG重参数化

一、原理解析&#xff1a; 复杂的卷积网络大都具有如下缺点&#xff1a; 复杂的多分支设计&#xff08;如ResNet中的残差相加和Inception中的分支连接&#xff09;使模型难以实现和自定义&#xff0c;降低了推理速度和降低了内存利用率。一些组件&#xff08;例如Xception和Mo…

RedisTemplate、StringRedisTemplate、序列化器配置

Lettuce和Jedis RedisTemplate是SpringDataRedis中对JedisApi的高度封装&#xff0c;提供了Redis各种操作、 异常处理及序列化&#xff0c;支持发布订阅。 首先我们要知道SpringData是Spring中数据操作的模块&#xff0c;包括对各种数据库的集成&#xff0c;比如我们之前学过…

Flutter——全网最精致木鱼APP可上架应用市场

研发背景 工作之余&#xff0c;闲来无事&#xff0c;想着研发一款用户可能会经常用到的一款APP,并且能够顺便掌握一下Flutter Material Design 3 UI&#xff0c;所以就有了这款比较精致的木鱼APP的诞生。 开源代码 https://github.com/z244370114/woodenfish

语义分割介绍

1. 定义 语义指具有人们可用语言探讨的意义&#xff0c;分割指图像分割。 语义分割(semantic segmentation)能够将整张图的每个部分分割开&#xff0c;使每个部分都有一定类别意义&#xff08;语义&#xff09;&#xff0c;让计算机可以理解图像。 语义分割是以描边的形式&…

【初阶数据结构篇】顺序表和链表算法题

文章目录 顺序表算法题移除元素删除有序数组中的重复项合并两个有序数组 链表算法题移除链表元素反转链表链表的中间结点合并两个有序链表链表分割链表的回文结构 顺序表算法题 不熟悉顺序表的可以先了解一下 顺序表实现方法 移除元素 给你一个数组 nums 和一个值 val&#x…

基于Xejen框架实现的C# winform鼠标点击器、电脑按键自动点击器的软件开发及介绍

功能演示 文章开始之前&#xff0c;仍然是先来个视频&#xff0c;以便用户知道鼠标连点器的基本功能 软件主界面 多功能鼠标连点器 快速点击&#xff1a; 痕即鼠标点击器可以设定每秒点击次数&#xff0c;让您轻松应对高频点击需求。 切换时长&#xff0c;即每次动作之间的间…

【安卓】Android Studio简易计算器(实现加减乘除,整数小数运算,正数负数运算)

目录 前言 运算效果 一、创建一个新的项目 二、编写xml文件&#xff08;计算器显示页面&#xff09; 三、实现Java运算逻辑 ​编辑 完整代码 xml文件代码&#xff1a; Java文件代码&#xff1a; 注&#xff1a; 前言 随着移动互联网的普及&#xff0c;手机应用程序已…

Linux_基础

文件结构 Linux的文件结构是一个倒的树状图&#xff0c;具体结构如下&#xff1a; bin&#xff1a;存放二进制文件 boot&#xff1a;存放系统启动文件 dev&#xff1a;存放设备文件 etc&#xff1a;存放系统管理时要用到的各种配置文件和子目录 lib&#xff1a;存放系统动…

【Vue2】3-使用Vue脚手架

目录 初始化脚手架 说明 具体步骤 模板项目的结构 关于不同版本的Vue vue.config.js配置文件 ref属性 配置项props mixin&#xff08;混入&#xff09; 插件 scoped样式 总结TodoList案例 webStorage&#xff08;浏览器本地存储&#xff09; TodoList本地存储 组…

UE4Editor.exe运行与调试 “-run=XX” 命令行

如果看到这么一条工作命令&#xff1a; %EnginePath%\Binaries\Win64\UE4Editor-Cmd.exe %ClientPath%\%ProjectName%.uproject -runHotPatcher {其它配置} 它意味着命令行&#xff0c;“-run” 后面接的内容是命令行&#xff0c; class UHotPatcherCommandlet :public UComma…

【初阶数据结构篇】栈的实现(赋源码)

文章目录 栈1 代码位置2 概念与结构1.1概念1.2结构 2 栈的实现2.1 栈的初始化和销毁2.1.1 初始化2.1.2 销毁 2.2 栈顶插入和删除数据2.2.1 栈顶插入数据&#xff08;压栈&#xff09;2.2.2 栈顶删除数据&#xff08;出栈&#xff09; 2.3 返回栈顶数据2.4 返回栈的有效数据个数…

C++类型强转

C(四)类型强转 新类型的强制转换可以提供更好的控制强制转换过程&#xff0c;允许控制各种不同种类的强 制转换。C提供了四种转化 static_cast&#xff0c;reinterpret_cast&#xff0c;dynamic_cast 和 const_cast 以满足不同需求&#xff0c;C风格的强制转换好处是&#xff…

【深度学习】语音合成,TTS,PaddleSpeech

https://paperswithcode.com/task/text-to-speech-synthesis https://github.com/PaddlePaddle/PaddleSpeech https://github.com/coqui-ai/TTS https://github.com/keonlee9420/Expressive-FastSpeech2 https://github.com/TensorSpeech/TensorflowTTS docker镜像&#x…

【笔记】人工智能大模型在电力系统运行控制中的应用综述及展望

据统计,截至 2019 年底,我国风电和光伏的装机容量已经达到 415 GW,美国的可再生能源全年发电量已超过燃煤发电,同时欧洲计划在 2050 年完成 100% 可再生能源互联电网的建设。为了响应国家提出的“碳达峰”“碳中和”政策,国家电网公司提出在有效保障能源安全供应的前提下,…

嵌入式人工智能(31-基于树莓派4B的气压传感器-BMP280)

1、气压传感器 气压传感器&#xff08;Pressure Sensor&#xff09;是一种用于测量气体压力的装置。它可以将气体压力转换为电信号输出&#xff0c;进而实现对气体压力的监测和控制。气压传感器广泛应用于工业自动化、气象观测、建筑监测、航空航天等领域。 气压传感器的工作…