【数据结构初阶】详解链表OJ题
目录
- 一.删除链表中等于给定值的节点
- 二.合并有序链表并返回
- 三.链表的回文结构
- 1.反转单链表
- 2.返回非空链表的中间节点
- 四.输出链表倒数第K个节点
- 五.基于给定值x分割单链表
- 六.返回两个链表的第一个中间节点
一.删除链表中等于给定值的节点
我们先来看第一题(题目链接):

因为我们需要从链表中删除满足条件的值,所以必须使用两个指针一个用来遍历链表,另一个记录上一个节点的位置。接着我们以遍历链表的指针不为空为循环条件编写代码,当当前节点的val值不等于给定x值时,就向下遍历,否则移除当前位置的节点。需要注意的一个特殊情况就是,链表第一个节点的值就等于给定的x值时,就需要移动头节点。代码如下:
struct ListNode* removeElements(struct ListNode* head, int val)
{struct ListNode*prev =NULL,*cur=head;while(cur){if(cur->val != val){prev=cur;cur=cur->next;}else {if(prev == NULL){head=cur->next;free(cur);cur=head;}else{prev->next=cur->next;free(cur);cur=prev->next;}}}return head;
}
二.合并有序链表并返回
我们接着看下一题(题目链接)

这题的思路我们可以新malloc一个链表,然后定义两个指针指向链表的头节点,然后遍历比较两个给的链表的val数值,将较小的插入到新链表中。最后返回即可。代码如下:
truct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2){struct ListNode*nextnode =(struct ListNode*)malloc(sizeof(struct ListNode));struct ListNode* cur=nextnode;struct ListNode* head=nextnode;if(!list1)return list2;else if(!list2)return list1;else{while(list1&&list2){if(list1->val<list2->val){cur->next=list1;cur=cur->next;list1=list1->next;cur->next=NULL;}else{cur->next=list2;cur=cur->next;list2=list2->next;cur->next=NULL;}}if(list1)cur->next=list1;if(list2)cur->next=list2;return head->next;}
}
三.链表的回文结构
1.反转单链表
我们看一下反转链表这一题(题目链接)

这题我们定义三个指针prev用来保存上一个节点的地址,初始化为NULL,curr初始化指向链表的头节点用来遍历链表,next用来保存遍历中下一个节点即可,代码如下,大家理解一下:
struct ListNode* reverseList(struct ListNode* head){struct ListNode*prev=NULL;struct ListNode*curr=head;while(curr){struct ListNode*next=curr->next;curr->next=prev;prev=curr;curr=next;}return prev;
}
2.返回非空链表的中间节点
(题目链接)

这题有个妙招------快慢指针,我们定义fast slow两个指针都指向头节点,不同的是快指针一次走两步而慢指针一次只走一步。考虑到链表是偶数个还是奇数个的问题,当快指针或者快指针的下一个节点走到NULL时,慢指针就走到了链表的中间节点,代码如下:
struct ListNode* middleNode(struct ListNode* head){struct ListNode*slow,*fast;slow=fast=head;while(fast && fast->next){fast=fast->next->next;slow=slow->next;}return slow;
}
基于上面两题的讲解我们来看下这题(题目链接)

这题我们的思路就是找到链表的中间节点后,反转后半段链表后,与前半段链表进行比较,如果在遍历走到空指针之前,全部相同则就是回文结构。
代码如下:
class PalindromeList {public:struct ListNode* reverseList(struct ListNode* head) {struct ListNode* prev = NULL;struct ListNode* curr = head;while (curr) {struct ListNode* next = curr->next;curr->next = prev;prev = curr;curr = next;}return prev;}struct ListNode* middleNode(struct ListNode* head) {struct ListNode* slow, *fast;slow = fast = head;while (fast && fast->next) {fast = fast->next->next;slow = slow->next;}return slow;}bool chkPalindrome(ListNode* A) {struct ListNode*mid= middleNode(A);struct ListNode* rhead=reverseList(mid);while(A && rhead){if(A->val != rhead->val)return false;A=A->next;rhead=rhead->next;}return true;}
};
四.输出链表倒数第K个节点
我们看下题目(题目链接)

这题使用快慢指针的话也是非常简单,我们定义快慢指针指向链表头节点,然后先让快指针走k步后再让快慢指针同时走,等快指针走到空指针时,满指针就走到了倒数第K个节点。
代码如下:
struct ListNode* FindKthToTail(struct ListNode* pListHead, int k ) {struct ListNode* slow=pListHead;struct ListNode* fast=pListHead;while(k--){if(fast == NULL)return NULL;fast=fast->next;}while(fast){slow=slow->next;fast=fast->next;}return slow;
}
五.基于给定值x分割单链表
我们看下一题(题目链接)

这题我们可以新malloc两个节点然后以给定值x将链表分割到两个链表中,最后将两个链表串起来即可。

代码如下:
class Partition {
public:ListNode* partition(ListNode* pHead, int x) {ListNode*guard1,*guard2,*tail1,*tail2;tail1=guard1=(ListNode*)malloc(sizeof(ListNode*));tail2=guard2=(ListNode*)malloc(sizeof(ListNode*));tail1->next=tail2->next=NULL;ListNode* cur=pHead;while(cur){if(cur->val<x){tail1->next=cur;cur=cur->next;tail1=tail1->next;}else {tail2->next=cur;cur=cur->next;tail2=tail2->next;}}tail1->next=guard2->next;tail2->next=NULL;return guard1->next; }
};
六.返回两个链表的第一个中间节点
我们先看一下题目(题目链接)

做这题时我们要想清楚,如果两个链表有相交的节点,那再这节点后两个链表都指向同一个地址

上图这种情况是不存在的
所以我们可以得知两个有相交节点的链表最后的节点的地址是相等的(当然相交节点后都相同,只因在单链表中尾节点比较好找)

代码如下:
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {int len1,len2;len1=len2=1;struct ListNode *tail1=headA;struct ListNode *tail2=headB;while(tail1){tail1=tail1->next;len1++;}while(tail2){tail2=tail2->next;len2++;}if(tail1 !=tail2)return NULL;int gap=abs(len1-len2);struct ListNode *longhead=headA;struct ListNode *shorthead=headB;if(len2>len1){longhead=headB;shorthead=headA;}while(gap--)longhead=longhead->next;while(shorthead != longhead){shorthead=shorthead->next;longhead=longhead->next;}return longhead;
}
相关文章:
【数据结构初阶】详解链表OJ题
目录一.删除链表中等于给定值的节点二.合并有序链表并返回三.链表的回文结构1.反转单链表2.返回非空链表的中间节点四.输出链表倒数第K个节点五.基于给定值x分割单链表六.返回两个链表的第一个中间节点一.删除链表中等于给定值的节点 我们先来看第一题(题目链接): 因为我们需…...
Java基本数据类型变量自动提升、强制类型转换、String基本类型使用
文章目录基本数据类型变量自动提升特殊情况强制类型转换String基本类型使用基本数据类型变量自动提升 规则: 将取值范围小(或容量小)的类型自动提升为取值范围大(或容量大)的类型 。 byte、short、char-->int-->…...
Redis锁与幂等性不得不说的故事
前言: 相信很多小伙伴对缓存锁都不陌生,但是简单的缓存锁想要用好还是需要一些功力。本文总结了笔者多年使用缓存所的一些心得,欢迎交流探讨~ 幂等模型: 幂等场景一般由查重写入两步操作组成,两步操作组成一个最小完…...
Spark 应用调优
Spark 应用调优人数统计优化摇号次数分布优化Shuffle 常规优化数据分区合并加 Cache优化中签率的变化趋势中签率局部洞察优化倍率分析优化表信息 : apply : 申请者 : 事实表lucky : 中签者表 : 维度表两张表的 Schema ( batchNum,carNum ) : ( 摇号批次,…...
synchronized 与 volatile 关键字
目录1.前言1.synchronized 关键字1. 互斥2.保证内存可见性3.可重入2. volatile 关键字1.保证内存可见性2.无法保证原子性3.synchronized 与 volatile 的区别1.前言 synchronized关键字和volatile是大家在Java多线程学习时接触的两个关键字,很多同学可能学习完就忘记…...
【0成本搭建个人博客】——Hexo+Node.js+Gitee Pages
目录 1、下载安装Git 2、下载安装Node.js 3、使用Hexo进行博客的搭建 4、更改博客样式 5、将博客上传到Gitee 6、更新博客 首先看一下Hexo的博客的效果。 1、下载安装Git Git 是一个开源的分布式版本控制系统,可以有效、高速地处理从很小到非常大的项目版本…...
【面试实战】认证授权流程及原理分析
认证授权流程及原理分析 1、认证 (Authentication) 和授权 (Authorization)的区别是什么?2、什么是Cookie ? Cookie的作用是什么?如何在服务端使用 Cookie ?3、Cookie 和 Session 有什么区别?如何使用Session进行身份验证?1、认证 (Authentication) 和授权 (Authorizatio…...
TPM命令解析之tpm2_startauthsession
参考网址链接:tpm2-tools/tpm2_startauthsession.1.md at master tpm2-software/tpm2-tools GitHub 命令名称 tpm2_startauthsession 功能 启动一个TPM会话。 命令形式 tpm2_startauthsession [OPTIONS] 描述 启动一个TPM会话。默认是启动一个试验(…...
第14章 局部波动率模型
这学期会时不时更新一下伊曼纽尔德曼(Emanuel Derman) 教授与迈克尔B.米勒(Michael B. Miller)的《The Volatility Smile》这本书,本意是协助导师课程需要,发在这里有意的朋友们可以学习一下,思…...
云原生周刊:开源“赢了”,但它可持续吗?
日前召开的 State of Open 会议上,开源“赢了”,但如果政府和企业不站出来确保生态系统在未来的弹性和可持续性,那么它仍然会失败。 OpenUK 首席执行官 Amanda Brock 在开幕式上表示,数字化和开源在过去 5 到 10 年的进步提升了工…...
读《企业IT架构转型之道》
本书还没读完,暂摘抄一些概念,因为自身做的新系统也在转型,从单体式到一体化一年来遇到很多问题有技术上的,也有团队协作的,过程是痛苦且复杂的,所以在刚翻阅前几十页时候,对于淘宝技术团队转型…...
Qt中的QTcpSocket、QWebSocket和QLocalSocket
同时实现了QTcpSocket、QWebSocket和QLocalSocket的简单通讯deamon,支持自动获取本机ip,多个客户端交互。在这个基础上你可以自己加错误检测、心跳发送、包封装解析和客户端自动重连等功能。 获取本机电脑ip: QString Widget::getIp() {QSt…...
枚举学习贴
1. 概述 1.1 是什么 枚举对应英文(enumeration, 简写 enum)枚举是一组常量的集合。可以这里理解:枚举属于一种特殊的类,里面只包含一组有限的特定的对象 1.2 枚举的二种实现方式 自定义类实现枚举使用 enum 关键字实现枚举 1.3 什么时候用 存在有限…...
【C++】30h速成C++从入门到精通(继承)
继承的概念及定义继承的概念继承(inheritance)机制是面向对象程序设计使代码可以复用的重要手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能,这样产生新的类,称派生类。继承呈现了面向对象程序…...
Java多线程还不会的进来吧,为你量身打造
💗推荐阅读文章💗 🌸JavaSE系列🌸👉1️⃣《JavaSE系列教程》🌺MySQL系列🌺👉2️⃣《MySQL系列教程》🍀JavaWeb系列🍀👉3️⃣《JavaWeb系列教程》…...
8 神经网络及Python实现
1 人工神经网络的历史 1.1 生物模型 1943年,心理学家W.S.McCulloch和数理逻辑学家W.Pitts基于神经元的生理特征,建立了单个神经元的数学模型(MP模型)。 1.2 数学模型 ykφ(∑i1mωkixibk)φ(WkTXb)y_{k}\varphi\left(\sum_{i1…...
使用QIS(Quantum Image Sensor)图像重建总结(1)
最近看了不少使用QIS重建图像的文章,觉得比较完整详细的还是Abhiram Gnanasambandam的博士论文:https://hammer.purdue.edu/articles/thesis/Computer_vision_at_low_light/20057081 1 介绍 讲述了又墨子的小孔成像原理,到交卷相机…...
【SpringCloud】SpringCloud教程之Nacos实战(二)
目录前言一.Nacos实现配置管理二.Nacos拉取配置三.Nacos配置热更新(自动刷新,不需要重启服务)1.在有Value注入变量所在类添加注解2.新建类用于属性加载和配置热更新四.Nacos多环境配置共享1.多环境共享配置2.配置的加载优先级测试3.配置优先级前言 Nacos实战一&…...
利用Qemu工具仿真ARM64平台
Windows系统利用Qemu仿真ARM64平台0 写在最前1 Windows安装Qemu1.1 下载Qemu1.2 安装Qemu1.3 添加环境变量1.4测试安装是否成功2. Qemu安装Ubuntu-Server-Arm-642.1 安装前的准备2.2 安装Ubuntu server arm 64位镜像3 Windows配置Qemu网络和传输文件3.1 参考内容3.2 Windows安装…...
【Hello Linux】进程控制 (内含思维导图)
作者:小萌新 专栏:Linux 作者简介:大二学生 希望能和大家一起进步! 本篇博客简介:简单介绍下进程的控制 包括进程启动 进程终止 进程等待 进程替换等概念 进程控制介绍进程创建fork函数fork函数的返回值fork函数的使用…...
使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...
龙虎榜——20250610
上证指数放量收阴线,个股多数下跌,盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型,指数短线有调整的需求,大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的:御银股份、雄帝科技 驱动…...
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以? 在 Golang 的面试中,map 类型的使用是一个常见的考点,其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...
MMaDA: Multimodal Large Diffusion Language Models
CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构…...
React19源码系列之 事件插件系统
事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...
NFT模式:数字资产确权与链游经济系统构建
NFT模式:数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新:构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议:基于LayerZero协议实现以太坊、Solana等公链资产互通,通过零知…...
【Android】Android 开发 ADB 常用指令
查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...
通过MicroSip配置自己的freeswitch服务器进行调试记录
之前用docker安装的freeswitch的,启动是正常的, 但用下面的Microsip连接不上 主要原因有可能一下几个 1、通过下面命令可以看 [rootlocalhost default]# docker exec -it freeswitch fs_cli -x "sofia status profile internal"Name …...
STM32标准库-ADC数模转换器
文章目录 一、ADC1.1简介1. 2逐次逼近型ADC1.3ADC框图1.4ADC基本结构1.4.1 信号 “上车点”:输入模块(GPIO、温度、V_REFINT)1.4.2 信号 “调度站”:多路开关1.4.3 信号 “加工厂”:ADC 转换器(规则组 注入…...
数据库正常,但后端收不到数据原因及解决
从代码和日志来看,后端SQL查询确实返回了数据,但最终user对象却为null。这表明查询结果没有正确映射到User对象上。 在前后端分离,并且ai辅助开发的时候,很容易出现前后端变量名不一致情况,还不报错,只是单…...
