【数据结构初阶】详解链表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函数的使用…...
脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)
一、数据处理与分析实战 (一)实时滤波与参数调整 基础滤波操作 60Hz 工频滤波:勾选界面右侧 “60Hz” 复选框,可有效抑制电网干扰(适用于北美地区,欧洲用户可调整为 50Hz)。 平滑处理&…...

SpringCloudGateway 自定义局部过滤器
场景: 将所有请求转化为同一路径请求(方便穿网配置)在请求头内标识原来路径,然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程
本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在聚客AI学院。 本文全面剖析RNN核心原理,深入讲解梯度消失/爆炸问题,并通过LSTM/GRU结构实现解决方案,提供时间序列预测和文本生成…...

企业如何增强终端安全?
在数字化转型加速的今天,企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机,到工厂里的物联网设备、智能传感器,这些终端构成了企业与外部世界连接的 “神经末梢”。然而,随着远程办公的常态化和设备接入的爆炸式…...
return this;返回的是谁
一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请,不同级别的经理有不同的审批权限: // 抽象处理者:审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...
JavaScript 数据类型详解
JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型(Primitive) 和 对象类型(Object) 两大类,共 8 种(ES11): 一、原始类型(7种) 1. undefined 定…...
小木的算法日记-多叉树的递归/层序遍历
🌲 从二叉树到森林:一文彻底搞懂多叉树遍历的艺术 🚀 引言 你好,未来的算法大神! 在数据结构的世界里,“树”无疑是最核心、最迷人的概念之一。我们中的大多数人都是从 二叉树 开始入门的,它…...
es6+和css3新增的特性有哪些
一:ECMAScript 新特性(ES6) ES6 (2015) - 革命性更新 1,记住的方法,从一个方法里面用到了哪些技术 1,let /const块级作用域声明2,**默认参数**:函数参数可以设置默认值。3&#x…...

深入解析光敏传感技术:嵌入式仿真平台如何重塑电子工程教学
一、光敏传感技术的物理本质与系统级实现挑战 光敏电阻作为经典的光电传感器件,其工作原理根植于半导体材料的光电导效应。当入射光子能量超过材料带隙宽度时,价带电子受激发跃迁至导带,形成电子-空穴对,导致材料电导率显著提升。…...
深入浅出JavaScript中的ArrayBuffer:二进制数据的“瑞士军刀”
深入浅出JavaScript中的ArrayBuffer:二进制数据的“瑞士军刀” 在JavaScript中,我们经常需要处理文本、数组、对象等数据类型。但当我们需要处理文件上传、图像处理、网络通信等场景时,单纯依赖字符串或数组就显得力不从心了。这时ÿ…...