单链表经典oj题 (一) 简单

1.删除指定节点数据(非尾节点),要求时间复杂度为O(1)

. - 力扣(LeetCode)

在之前我们将单链表删除指定节点的操作是先遍历找到pos的前一个结点,然后再进行删除,但是现在要求再O(1)时间内完成,这就要想一种新的思路来解决这个问题了。

我们不能去遍历链表,但是我们能找到要删除的节点的下一个节点,这个题的要求是删除那个数据,并不是说要删除这个节点,那么我们就可以将要删除的节点的数据与下一个结点的数据进行调换,这样问题就转换为了删除下一个节点了,怎样处理就很简单了。

思路有了,而这个题的代码也很简单,那就直接放上答案。

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

2.返回倒数第k个节点

. - 力扣(LeetCode)

看到这个题的第一个思路就是暴力求解,首先遍历一遍链表,统计节点个数 n ,然后第n+1-k个节点就是倒数第 k 个节点 。

int kthToLast(struct ListNode* head, int k){int n=0;struct ListNode* cur=head;while(cur){n++;cur=cur->next;}n=n-k+1;cur=head;while(--n)//第n个节点只要循环n-1次{cur=cur->next;}return cur->val;}

但是这个题还有一这种思路只用遍历一遍链表,我们用快慢指针来解决,首先fast先往后走k步

这时slow和fast再同时往后走,当fast为NULL的时候,slow就是倒数第k个节点

这样实现起来代码也很简单

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

因为题目中明确说明了k是有效的,所以我们就不用判断fast在第一个循环就走到了NULL的情况的。

掌握了上面的题,再来做一个相似的题

删除链表的倒数第N个节点,并返回新的头节点

https://leetcode.cn/problems/SLwz0R/

这个题是要删除倒数第N个节点,那我们首先要找到倒数第N+1个节点,修改这个节点的next。

这个题目中给的信息是N<=sz,这就说明有可能删除的是头节点的,所以在fast走完N步之后,要先判断fast是否已经为空,如果fast已经是NULL了,则说明要删除的是头节点。

如果这时候fast不为空,则说明要删的不是头节点,这时候fast再往前走一步,

struct ListNode* removeNthFromEnd(struct ListNode* head, int n){struct ListNode* fast=head;struct ListNode* slow=head;while(n--){fast=fast->next;}if(fast==NULL)//判断要删除的是否是头节点{head=head->next;free(slow);return head;}//不是头节点在快慢指针继续走fast=fast->next;while(fast){fast=fast->next;slow=slow->next;}struct ListNode* del=slow->next;slow->next=del->next;free(del);return head; }

3.反转链表

. - 力扣(LeetCode)

反转链表的思路就是遍历每个节点然后头插,

要注意的就是要记录cur的下一个节点的地址。

struct ListNode* reverseList(struct ListNode* head) {struct ListNode* newhead=NULL;struct ListNode* cur=head;struct ListNdoe* next=NULL;while(cur){//记录下一个节点next=cur->next;//头插cur->next=newhead;//换头newhead=cur;//迭代cur=next;}return newhead;
}

写完这段代码之后先思考一下空链表的问题,由于我们newhead初始化为NULL,如果是空链表的话,返回时的newhead也是NULLL,所以不会有问题。

4.合并两个升序链表

. - 力扣(LeetCode)

合并两个升序链表我们很容易想到在之前的数组阶段见过的合并两个升序数组,当时我们使用的是归并排序,在链表中我们同样可以用归并来合并两个链表。首先我们用一个哨兵位的头节点来接收归并后的链表,因为合并升序链表要用到尾插,我们再用一个tail来记录新链表的尾。

然后我们用两个指针来遍历两个链表,取小的尾插到新链表上去,直到cur1或者cur2指向NULL,之后再将没遍历完的链表插入到新链表后面。

struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) {struct ListNode* guard=(struct ListNode*)malloc(sizeof(struct ListNode));guard->next=NULL;struct ListNode* tail=guard;struct ListNode* cur1=list1;struct ListNode* cur2=list2;while(cur1&&cur2){if(cur1->val<=cur2->val){tail->next=cur1;tail=cur1;cur1=cur1->next;}else{tail->next=cur2;tail=cur2;cur2=cur2->next;}}if(cur1)//cur2遍历完了{tail->next=cur1;}else{tail->next=cur2;}struct ListNode* head=guard->next;free(guard);return head;}

5.链表相交

. - 力扣(LeetCode)

这个题我们首先要判断两个链表是否相交,判断相交不难,因为如果两个链表相交的话,他们的尾节点是相同的,所以我们可以遍历两个链表,判断两个链表的尾节点是否相同。

    if(!headA||!headB)//有一个空链表就返回NULLreturn NULL;struct ListNode* cur1=headA;struct ListNode* cur2=headB;while(cur1->next){cur1=cur1->next;}while(cur2->next){cur2=cur2->next;}if(cur1!=cur2)//不相交{return NULL;}else{//找相交节点}

我们首先判断一下两个链表是否有空链表,如果有一个是空链表或者都是空链表,则没有相交。

在判断完是否相交之后,如何去找相交的节点呢?

首先我们是可以求出两个链表的节点的个数的,也就是链表的长度,当链表相交之后后半段的长度是相等的,所以两个链表的长度差就差在相交之前的部分。

那么我们是不是可以让长的链表先走 他们的长度差 的步数,如何在两个指针一起走,这样他们相遇的节点就是相交的起始节点。

struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {if(!headA||!headB)//有一个空链表就返回NULLreturn NULL;struct ListNode* cur1=headA;struct ListNode* cur2=headB;int lenA=0;int lenB=0;while(cur1->next){cur1=cur1->next;lenA++;}while(cur2->next){cur2=cur2->next;lenB++;}if(cur1!=cur2)//不相交{return NULL;}else{//找相交节点struct ListNode* longlist = (lenA>lenB?headA:headB);struct ListNode* shortlist = (lenA>lenB?headB:headA);//求出长度差int gap=abs(lenA-lenB);//长链表先走gap步while(gap--){longlist=longlist->next;}//同时走while(longlist!=shortlist){longlist=longlist->next;shortlist=shortlist->next;}return shortlist;}}

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

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

相关文章

Kubernetes有状态任务

有状态任务是指执行期间需要维护一定状态或数据的任务或工作。这些任务通常需要记录并维护数据、状态、上下文或进度信息&#xff0c;并且这些信息在任务执行期间保持持久。有状态任务的解决目标是确保任务在不同的环境、节点或时间点之间维持一致的状态和标识。这种任务通常需…

2-3 AUTOSAR ASW Runable可运行实体

返回总目录->返回总目录<- 目录 一、概述 二、RTE Event 一、概述 运行实体(Runnable Entity,RE)是一段可执行的代码,其包含实际实现的函数(具体的逻辑算法或者操作)。一个软件组件可以包含一个或者多个运行实体。 Runnable就是SWC中的函数,而在AutoSAR架构在被…

Windows Server 2012 R2安装远程桌面服务

文章目录 一、打开【服务器管理器】二、点击【添加角色和功能】三、点击【下一步】四、点击【下一步】五、点击【下一步】![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/05b61a830faf477e81f858ec00bbdfff.png)六、勾选【远程桌面服务】→点击【下一步】七、点击【…

代码执行漏洞

原理&#xff1a;没有对接口输入的内容进行严格的判断 造成攻击者精心构造的代码非法执行 当应用在调用一些能将字符转化为代码的函数(如PHP中的eval)时&#xff0c;没有考虑用户是否能控 制这个字符串&#xff0c;这就会造成代码执行漏洞。 相 关 函 数 &#xff1a; PHP&…

sharo反序列化漏洞

启动docker 服务 sudo service docker start 打开靶场 sudo docker run -d -p 80:8080 medicean/vulapps:s_shiro_1 输入docker虚拟机地址打开靶机sharo框架 如何利用漏洞 打开工具目录在终端中打开 输入靶机地址 打开yaki监听端口可以设置为6666 返回工具填写靶机ip和端口 …

MongoDB聚合运算符:$millisecond

文章目录 语法使用举例 $millisecond聚合运算符返回日期中毫秒部分的数字值为0到999之间 语法 { $millisecond: <dateExpression> }参数说明&#xff1a; <dateExpression>为可解析为Date、Timestamp或ObjectID或者参数也可以是一个文档&#xff1a; { date: &l…

Windows应急响应

1.排查隐藏账号 查看注册表 找到攻击者用户目录文件 排查用户异常 eventvwr.msc 分析用户登录日志 排查可疑端口 排查可疑进程 检查启动项、计划任务和服务 查看系统补丁信息 安装火绒&#xff0c;在安全工具里有火绒剑 计划任务 使用D盾对主机进行检测&#xff0c;发现隐藏账户…

windbg托管内存泄漏排查

1、!address -summary 查看内存占用 主要查看以下两项 Heap&#xff1a;NT 堆 &#xff08;同 !heap -s)&#xff0c;Size过大&#xff0c;可能有非托管内存泄露 MEM_COMMIT&#xff1a;处于提交状态的内存大小&#xff0c;Size过大&#xff0c;可能有内存泄露 Heap …

中非绿色能源合作走深走实

近日&#xff0c;第十六届非洲能源大会在南非立法首都开普敦举行&#xff0c;探讨实现非洲能源转型的可持续解决方案。近年来&#xff0c;中国与非洲国家不断加强绿色能源合作&#xff0c;促进双方优势资源互补&#xff0c;逐步探索合作共赢的绿色能源合作方案。 势头良好 近年…

【201】Java8读取JSON树形结构并插入到MySQL数据库表中

我写了一个 maven 项目的 Demo&#xff0c;用来演示 JAVA8 如何读取 JSON 文件树形结构&#xff0c;并将这种树形结构保存到 MySQL 中。 json文件 city.json {"name": "山东省","sub": [{"name": "青岛市","sub"…

什么是SYN攻击,有什么办法防御SYN攻击

自进入数字化互联网时代&#xff0c;网络技术给我们带来了许多服务&#xff0c;为人们的生活增添了许多便利。但同时&#xff0c;网络安全问题也日益凸显&#xff0c;其中DDoS攻击&#xff0c;即分布式拒绝服务攻击&#xff0c;已经成为一种常见的网络威胁。这种攻击方式通过控…

数据结构与算法实验10-查找和排序

、实验目的 掌握运用数据结构两种基本运算查找和排序,并能通过其能解决应用问题。 二、实验软硬件要求 1、VC 6.0 三、实验预习 查找排序相关算法 四、实验内容&#xff08;实验步骤、测试数据等&#xff09; 为宿舍管理人员编写一个宿舍管理查询软件, 程序采用交互工作…

Python爬取公众号封面图(零基础也能看懂)

&#x1f4da;博客主页&#xff1a;knighthood2001 ✨公众号&#xff1a;认知up吧 &#xff08;目前正在带领大家一起提升认知&#xff0c;感兴趣可以来围观一下&#xff09; &#x1f383;知识星球&#xff1a;【认知up吧|成长|副业】介绍 ❤️感谢大家点赞&#x1f44d;&…

c语言:大端小端(真实考试题目)

请简述大端字节序和小端字节序的概念&#xff0c;设计一个程序&#xff08;代码&#xff09;判断当前机器的字节序 大端&#xff08;存储&#xff09;字节序&#xff1a;是指数据的低位保存在内存的高地址中&#xff0c; 数据的高位保存在内存的低地址中。 小端&#xff08;存储…

【RISC-V 指令集】RISC-V 向量V扩展指令集介绍(十)- 向量整数算术指令

1. 引言 以下是《riscv-v-spec-1.0.pdf》文档的关键内容&#xff1a; 这是一份关于向量扩展的详细技术文档&#xff0c;内容覆盖了向量指令集的多个关键方面&#xff0c;如向量寄存器状态映射、向量指令格式、向量加载和存储操作、向量内存对齐约束、向量内存一致性模型、向量…

文献速递:深度学习胰腺癌诊断--深度学习算法用于从疾病轨迹预测胰腺癌风险

文献速递&#xff1a;深度学习胰腺癌诊断--深度学习算法用于从疾病轨迹预测胰腺癌风险 麦田医学 美好事物中转站 2024-04-02 14:36 Title 题目 A deep learning algorithm to predict risk of pancreatic cancer from disease trajectories 深度学习算法用于从疾病轨迹预测…

Redis 客户端

Redis 客户端 客户端-服务器结构 Redis 同 Mysql 一样&#xff0c;也是一个客户端-服务器结构的程序&#xff0c;结构如下图&#xff1a; 注&#xff1a;Redis 客户端和服务器可以在同一个主机上&#xff0c;也可以在不同主机上 Redis 客户端的多种形态 自带的命令行客户端&…

HTML:表单

案例&#xff1a; <!DOCTYPE html> <html> <head><meta charset"UTF-8"><title>报名表</title> </head> <body><form action"demo/welcome.php" method"post">名字&#xff1a;<inpu…

【经典算法】LeetCode25:K 个一组翻转链表(Java/C/Python3,Hard)

#算法 目录 题目描述思路及实现方式一&#xff1a;递归思路代码实现Java 版本C 语言版本Python3 版本 复杂度分析 方式二&#xff1a;迭代和原地反转思路代码实现Java 版本C 语言版本Python3 版本 复杂度分析 总结相似题目 标签&#xff1a;链表、递归 题目描述 给你链表的头…

金融企业区域集中库的设计构想和测试验证

导读 本文探讨了金融企业区域集中库的设计构想和测试验证&#xff0c;包括架构设想、数据库整合场景测试及优势和使用设想。作者提出利用 TiDB 数据库产品集中建设区域集中库&#xff0c;解决 MySQL 存量节点的整合问题&#xff0c;实现部署的标准化、按需扩展和统一运维管理。…