当前位置: 首页 > news >正文

算法_链表专题---持续更新

文章目录

  • 前言
  • 两数相加
    • 题目要求
    • 题目解析
    • 代码如下
  • 两两交换链表中的结点
    • 题目要求
    • 题目解析
    • 代码如下
  • 重排链表
    • 题目要求
    • 题目解析
    • 代码如下
  • 合并K个升序链表
    • 题目要求
    • 题目解析
  • K个一组翻转链表
    • 题目要求
    • 题目解析
    • 代码如下

前言

本文将记录leetcode链表算法题解,包含题目有:两数相加、两两交换链表中的节点、重排链表、合并K个升序链表、K个一组翻转链表

两数相加

https://leetcode.cn/problems/add-two-numbers/

题目要求

在这里插入图片描述

题目解析

已经给你两个逆序的链表,如果不是给逆序的,还需要自己逆序一下,因为加法是从低位到高位相加的,重点是低位到高位的过程中可能会有进位,关键的就是这个进位,逆序后(就相当于正常顺序的低位开始相加,因为我们的逻辑就是从链表的头部开始加,依次遍历向后走),链表从头部依次相加向后走,有进位进位即可 题目给的两个链表是已经逆序过的,包括最后的要求结果也是逆序的,不需要做任何修改

在这里插入图片描述

代码如下

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     ListNode *next;*     ListNode() : val(0), next(nullptr) {}*     ListNode(int x) : val(x), next(nullptr) {}*     ListNode(int x, ListNode *next) : val(x), next(next) {}* };*/
class Solution {
public:ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {ListNode* newhead = new ListNode(0);   //新链表ListNode* tail = newhead;    //尾节点ListNode * cur1 = l1;ListNode * cur2 = l2;int ret = 0;    //进位//注意这种情况:当两个链表节点都为空时,进位不为空,需要进位while(cur1 || cur2 || ret){//第一个链表中节点不为空if(cur1){ret += cur1->val;cur1 = cur1->next;}//第二个链表中节点不为空if(cur2){ret += cur2->val;cur2 = cur2->next;}tail->next = new ListNode(ret % 10);tail = tail->next;ret /= 10;  //进位}//释放new出的内存tail = newhead->next;delete newhead;return tail;}
};

两两交换链表中的结点

https://leetcode.cn/problems/swap-nodes-in-pairs/description/

题目要求

在这里插入图片描述

题目解析

题目要求两两交换相邻的节点,且不能修改节点的值,我们只需要改变节点的next指针的指向即可,为了方便两两交换我们引入一个哨兵位(当交换1、2节点时,只需要让哨兵位->next指向2这个节点....省略,这样方便很多) 要求是两两交换,实际上会影响到四个节点,哨兵位、cur、next、nnext,因为交换节点的时候,我们需要修改对应的next指向

在这里插入图片描述

当需要进行下一次两两交换的时候,先把prev向后移动两位
因为进行3、4节点交换的时候,1节点的next会指向4节点了
因此我们需要一个prev

代码如下

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     ListNode *next;*     ListNode() : val(0), next(nullptr) {}*     ListNode(int x) : val(x), next(nullptr) {}*     ListNode(int x, ListNode *next) : val(x), next(next) {}* };*/
class Solution {
public:ListNode* swapPairs(ListNode* head) {ListNode* dummyHead = new ListNode(0);    //虚拟头节点dummyHead->next = head;ListNode* prev = dummyHead;//cur、next不为空while(prev->next !=nullptr && prev->next->next != nullptr){ListNode* cur = prev->next;ListNode* next = cur->next;ListNode* nnext = next->next;//两两交换(cur、next)prev->next = next;next->next = cur;cur->next = nnext;//向后移动prev = prev->next->next;}return dummyHead->next;}
};

重排链表

https://leetcode.cn/problems/reorder-list/description/

题目要求

在这里插入图片描述

题目解析

这道题本质上是一道模拟题,根据题目以及示例模拟出设计过程,这道题比较综合,会运用到链表的中间节点、反转链表这两道基础题的方法
模拟
找到中间节点,分割成两个链表,并将后面一个链表反转
按照先添加第一个链表的第一个节点,再添加第二个链表的第一个节点,先添加第一个链表的第二个节点
再添加第二个链表的第二个节点的顺序以此类推
在这里插入图片描述

1、首先利用快慢指针找到中间位置(快指针一次前进两步,慢指针一步,这样快指针每次都是慢指针的二倍,当快指针走到链表结尾时,慢指针就走到中间位置)
2、链表分割,这里非常重要,我第一次做的时候就忘记将链表断开了,记得将第一个链表的结尾节点的next置空,这里的逻辑是将slow->next位置开始作为第二个链表(不包含当前slow指针指向的节点)
当然也可以用包含slow以及后面的所有节点作为第二个链表
3、链表反转,也就是逆序,不断地将节点头插到新空间即可
4、按照模拟顺序依次重组链表
由于将slow->next位置开始作为第二个链表,所以无论是奇数个还是偶数个
节点,都是第一个链表长于第二个链表,因此当重组的时候,循环条件是第一个链表节点不为空,这样当第一个链表节点出现为空的时候,第二个链表肯定早早就结束了,就可以重组所有节点了
以下是使用快慢双指针找中间节点(slow指针指向的位置)的奇数以及偶数讨论
在这里插入图片描述

代码如下

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     ListNode *next;*     ListNode() : val(0), next(nullptr) {}*     ListNode(int x) : val(x), next(nullptr) {}*     ListNode(int x, ListNode *next) : val(x), next(next) {}* };*/
class Solution {
public:void reorderList(ListNode* head) {//当链表节点数为1或2时,直接返回if(head->next == nullptr || head->next->next == nullptr) return;//利用快慢指针找到中间位置ListNode* fast = head;ListNode* slow = head;//链表中的节点为奇数/偶数while(fast&&fast->next){fast = fast->next->next;slow = slow->next;}//分割断开为两个链表ListNode* cur = slow->next;slow->next = nullptr;//翻转第二个链表ListNode* head2 = new ListNode(0);ListNode* curr = cur->next; //保存下一个节点while(cur){            curr = cur->next;cur->next = head2->next;head2->next = cur;cur = curr;}ListNode* ret = new ListNode(0);ListNode* prev = ret;ListNode* cur1 = head;ListNode* cur2 = head2->next;//分割时按照slow->next慢指针的后一个节点进行分割,所以第一个链表是最长的,第一个链表遍历完毕就结束while(cur1){prev->next = cur1;prev = prev->next;cur1 = cur1->next;if(cur2){prev->next = cur2;prev = prev->next;cur2 = cur2->next;}}head = ret;}
};

合并K个升序链表

https://leetcode.cn/problems/merge-k-sorted-lists/

题目要求

在这里插入图片描述

题目解析

合并K个升序链表,我们自然能想到使用合并两个升序链表的方法来解决问题,但是这样事件复杂度是比较高的。 使用优先级队列,创建一个小根堆,先将每个链表的头节点放入优先级队列中,然后取出堆顶的节点(堆顶的节点就是当前堆中所有元素最小的),取出这个节点后,这个节点必然是属于某个链表的,在将该节点后一个节点加入优先级队列中(这样就可以做到所有链表的节点都能比较一遍),循环往复,持续地取出堆顶的元素
/*** Definition for singly-linked list.* struct ListNode {*     int val;*     ListNode *next;*     ListNode() : val(0), next(nullptr) {}*     ListNode(int x) : val(x), next(nullptr) {}*     ListNode(int x, ListNode *next) : val(x), next(next) {}* };*/
class Solution {
public://C++标准库不提供对自定义数据类型的排序规则(ListNode),所以需要重载operator()struct cmp{bool operator()(const ListNode* l1, const ListNode* l2){return l1->val > l2->val;}};ListNode* mergeKLists(vector<ListNode*>& lists) {//创建一个小根堆(根据给定的比较规则自动对元素进行排序)priority_queue<ListNode*, vector<ListNode*>, cmp> heap;//将所有链表的头节点先添加入小根堆中for(auto l : lists){//链表可能为空if(l)heap.push(l);}ListNode* ret = new ListNode(0);    //虚拟头节点ListNode* prev = ret;while(!heap.empty()){ListNode* t = heap.top();prev->next = t;heap.pop();prev = prev->next;  //更新if(t->next) heap.push(t->next); //将每个链表都向后推进}prev = ret->next;delete ret;return prev;}
};

K个一组翻转链表

https://leetcode.cn/problems/reverse-nodes-in-k-group/description/

题目要求

在这里插入图片描述

题目解析

这道题不需要什么技巧,只需要把过程模拟出来就好,首先读题,k个节点为一组,并按照一组为单位进行逆序,那么我们需要先将总节点的个数算出,再计算出一共需要逆序多少组,两个循环就可以搞定
for(逆序多少组)
{for(每一组需要逆序多少个节点) {}
}
最后将剩下不需要逆序的节点接在最后面

逆序逻辑
在这里插入图片描述
在这里插入图片描述
注意
当逆序到下一组的时候,我们是需要提前保存第一组逆序的第一个节点的,ListNode* tmp = cur,因为第一个
节点逆序后一定是在第一组的最后一个位置(紧接第二组)
在这里插入图片描述

代码如下

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     ListNode *next;*     ListNode() : val(0), next(nullptr) {}*     ListNode(int x) : val(x), next(nullptr) {}*     ListNode(int x, ListNode *next) : val(x), next(next) {}* };*/
class Solution {
public:ListNode* reverseKGroup(ListNode* head, int k) {//遍历链表计算总节点数ListNode* num = head;int n = 0;  //总节点数while(num){num = num->next;n++;}int group = n/k;ListNode* dummyHead = new ListNode(0);  //虚拟头节点ListNode* prev = dummyHead; //cur的前一个节点ListNode* cur = head;    //当前节点for(int i = 0; i < group; i++){ListNode* tmp = cur;    //保存前一个位置for(int j = 0; j < k; j++){ListNode *next = cur->next; //保存下一个节点cur->next = prev->next;prev->next = cur;cur = next;}prev = tmp; //更新下一组逆序的前一个位置}//加上不需逆序的节点if(cur) prev->next = cur;//释放,防止内存泄漏prev = dummyHead->next;delete dummyHead;return prev;}
};

相关文章:

算法_链表专题---持续更新

文章目录 前言两数相加题目要求题目解析代码如下 两两交换链表中的结点题目要求题目解析代码如下 重排链表题目要求题目解析代码如下 合并K个升序链表题目要求题目解析 K个一组翻转链表题目要求题目解析代码如下 前言 本文将记录leetcode链表算法题解&#xff0c;包含题目有&a…...

在Windows MFC\C++编程中,如何使用OnCopyData函数

在C中&#xff0c;OnCopyData 函数通常不是标准C库的一部分&#xff0c;而是与特定的图形用户界面&#xff08;GUI&#xff09;框架相关联&#xff0c;如Microsoft Foundation Classes (MFC) 或 Windows API 编程。在MFC应用程序中&#xff0c;OnCopyData 是用于处理来自其他应…...

【Qt】项目代码

main.cpp文件 argc&#xff1a;命令行参数个数。*argv[ ]&#xff1a;每一个命令行参数的内容。main的形参就是命令行参数。QApplication a(argc, argv) 编写一个Qt的图形化界面程序&#xff0c;一定需要QApplication对象。 widget w; 在创建项目的时候&#xff0c;勾选widg…...

MySQL中常用工具

MySQL自带的系统数据库 常用工具 MySQL mysqladmin mysqlbinlog mysqldump mysqlimport/source mysqlimport只能导入文本文件&#xff0c;不能导入sql文件...

关于儿童编程语言

青少年通常会通过Scratch或Python开始学习编程。在这两种语言中&#xff0c;代码的编写&#xff08;或者在Scratch中是构建&#xff09;方式类似于英语&#xff0c;这使得初学者更容易学习。Scratch的一个重要卖点是对视觉和运动感知学习者非常友好。这些代码块按颜色编码&…...

[io]进程间通信 -信号函数 —信号处理过程

sighandler_t signal(int signum, sighandler_t handler); 功能&#xff1a; 信号处理函数 参数&#xff1a; signum&#xff1a;要处理的信号 handler&#xff1a;信号处理方式 SIG_IGN&#xff1a;忽略信号 SIG_DFL&#xff1a;执行默认操作 handler&#xff1a;捕捉信 …...

RoboDK的插件

目录 collision-free-planner&#xff1a; opc-ua&#xff1a; collision-free-planner&#xff1a; RoboDK 的无碰撞规划器插件使用概率路线图 (PRM) 自动在机器人工作空间内创建无碰撞路径。 有关无碰撞规划器的更多信息&#xff0c;请访问我们的 文档。 生成参数无碰撞…...

List<HashMap<String, Object>>排序

如果列表中的元素类型是List<HashMap<String, Object>>&#xff0c;排序时需要考虑到value可能是任意类型的对象。在这种情况下&#xff0c;你可以针对具体的类型进行比较&#xff0c;或者使用Comparable接口来确保对象可以被正确比较。 示例代码 假设我们想要根据…...

【大数据】探索大数据基础知识:定义、特征与生态系统

欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;欢迎订阅相关专栏&#xff1a; 工&#x1f497;重&#x1f497;hao&#x1f497;&#xff1a;野老杂谈 ⭐️ 全网最全IT互联网公司面试宝典&#xff1a;收集整理全网各大IT互联网公司技术、项目、HR面试真题.…...

营销材料翻译质量对销售渠道的影响

在当今的全球市场中&#xff0c;与不同受众进行有效沟通的能力对于企业的成功至关重要。营销材料的高质量翻译在通过销售渠道塑造客户旅程方面发挥着重要作用&#xff0c;影响着知名度、参与度、转化率和保留率。方法如下&#xff1a; 提高品牌知名度 在销售渠道的顶端&#x…...

centos7.9安装k8s 1.3

centos7.9安装k8s 1.3 k8s环境规划&#xff1a;初始化修改网卡配置两台服务器都执行 配置阿里yum源 安装containerd服务安装初始化k8s需要的软件包kubeadm初始化k8s集群 扩容k8s集群-添加第一个工作节点安装kubernetes网络组件-Calico测试在k8s创建pod是否可以正常访问网络和co…...

【第七节】python多线程及网络编程

目录 一、python多线程 1.1 多线程的作用 1.2 python中的 threading 模块 1.3 线程锁 二、python网络编程 2.1 通过socket访问网络 2.2 python2.x中的编码问题 2.3 python3的编码问题 一、python多线程 1.1 多线程的作用 多线程技术在计算机编程中扮演着重要的角色&a…...

Linux Shell编程--变量

前言&#xff1a;本博客仅作记录学习使用&#xff0c;部分图片出自网络&#xff0c;如有侵犯您的权益&#xff0c;请联系删除 变量&#xff1a; bash作为程序设计语言和其它高级语言一样也提供使用和定义变量的功能 预定义变量、环境变量、自定义变量、位置变量 一、自定义变…...

软文写作必须掌握的技巧有哪些?

现代互联网飞速发展的时代&#xff0c;硬广逐渐变的效果越来越差&#xff0c;而软文推广已经成为网络营销的重要组成部分了&#xff0c;一篇好的软文往往能为你的产品、网站带来意想不到的效果。 用于做营销的软文&#xff0c;我们不能像写普通文章那样随意。一篇优质的软文会让…...

探索灵办AI:智能办公的好帮手

引言 随着AI工具的增多&#xff0c;选择合适的AI助手变得尤为重要。ChatGPT的订阅费用高且功能单一&#xff0c;很多小伙伴开始寻找更具性价比和多功能的替代品。灵办AI以其便捷、高效、多功能的特点&#xff0c;成为许多朋友的新宠。 灵办AI助手是一款多功能的全能AI助手&am…...

gin-vue-admin框架遇到AxiosError:Network Error怎么解决?

flipped-aurora/gin-vue-admin: &#x1f680;ViteVue3Gin的开发基础平台&#xff0c;支持TS和JS混用。它集成了JWT鉴权、权限管理、动态路由、显隐可控组件、分页封装、多点登录拦截、资源权限、上传下载、代码生成器【可AI辅助】、表单生成器和可配置的导入导出等开发必备功能…...

作业zzz

【考查点】 考查SpringBoot相关的知识点&#xff0c;包括&#xff1a;依赖注入&#xff08;DI&#xff09;、面向切面编程&#xff08;AOP&#xff09;&#xff0c;以及常用的SpringBoot组件。 【作业要求】 利用spring-boot-starter-web来搭建一个web服务。完成简单的用户管…...

python 空list如何表示

创建空列表&#xff1a; L List() 或者&#xff1a; L [] 这时L就是一个空列表。 需要注意的是&#xff0c;空列表不是None&#xff0c;因此 L [] If L is not None:# 这里的代码总是会被执行 检查列表是否为空要使用len()&#xff1a; L [] if len(L):# 这里的代码不会执…...

C++ const、constexpr与consteval作用与区别

C const、constexpr与consteval作用与区别 在C 常量表达式和编译时优化中&#xff0c;我们已经提到了常量、编译时常量与运行时常量的概念。为了加深理解&#xff0c;我们再重新明晰一下这三者的概念。 常量&#xff1a;初始化之后便不可修改的量。在c中使用const修饰的“变量”…...

solidity 数学和密码学函数

数学和密码学函数为开发者提供了一系列强大的工具&#xff0c;用于执行各种数学运算和加密操作 addmod(uint x, uint y, uint k) returns (uint) 计算 (x y) % k&#xff0c;加法会在任意精度下执行&#xff0c;并且加法的结果即使超过 2**256 也不会被截取。 从 0.5.0 版本…...

Psychopy音频的使用

Psychopy音频的使用 本文主要解决以下问题&#xff1a; 指定音频引擎与设备&#xff1b;播放音频文件 本文所使用的环境&#xff1a; Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...

工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配

AI3D视觉的工业赋能者 迁移科技成立于2017年&#xff0c;作为行业领先的3D工业相机及视觉系统供应商&#xff0c;累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成&#xff0c;通过稳定、易用、高回报的AI3D视觉系统&#xff0c;为汽车、新能源、金属制造等行…...

HashMap中的put方法执行流程(流程图)

1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中&#xff0c;其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下&#xff1a; 初始判断与哈希计算&#xff1a; 首先&#xff0c;putVal 方法会检查当前的 table&#xff08;也就…...

力扣热题100 k个一组反转链表题解

题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...

高防服务器价格高原因分析

高防服务器的价格较高&#xff0c;主要是由于其特殊的防御机制、硬件配置、运营维护等多方面的综合成本。以下从技术、资源和服务三个维度详细解析高防服务器昂贵的原因&#xff1a; 一、硬件与技术投入 大带宽需求 DDoS攻击通过占用大量带宽资源瘫痪目标服务器&#xff0c;因此…...

Mac flutter环境搭建

一、下载flutter sdk 制作 Android 应用 | Flutter 中文文档 - Flutter 中文开发者网站 - Flutter 1、查看mac电脑处理器选择sdk 2、解压 unzip ~/Downloads/flutter_macos_arm64_3.32.2-stable.zip \ -d ~/development/ 3、添加环境变量 命令行打开配置环境变量文件 ope…...

Axure零基础跟我学:展开与收回

亲爱的小伙伴,如有帮助请订阅专栏!跟着老师每课一练,系统学习Axure交互设计课程! Axure产品经理精品视频课https://edu.csdn.net/course/detail/40420 课程主题:Axure菜单展开与收回 课程视频:...

Pandas 可视化集成:数据科学家的高效绘图指南

为什么选择 Pandas 进行数据可视化&#xff1f; 在数据科学和分析领域&#xff0c;可视化是理解数据、发现模式和传达见解的关键步骤。Python 生态系统提供了多种可视化工具&#xff0c;如 Matplotlib、Seaborn、Plotly 等&#xff0c;但 Pandas 内置的可视化功能因其与数据结…...

新版NANO下载烧录过程

一、序言 搭建 Jetson 系列产品烧录系统的环境需要在电脑主机上安装 Ubuntu 系统。此处使用 18.04 LTS。 二、环境搭建 1、安装库 $ sudo apt-get install qemu-user-static$ sudo apt-get install python 搭建环境的过程需要这个应用库来将某些 NVIDIA 软件组件安装到 Je…...

Python爬虫(四):PyQuery 框架

PyQuery 框架详解与对比 BeautifulSoup 第一部分&#xff1a;PyQuery 框架介绍 1. PyQuery 是什么&#xff1f; PyQuery 是一个 Python 的 HTML/XML 解析库&#xff0c;它采用了 jQuery 的语法风格&#xff0c;让开发者能够用类似前端 jQuery 的方式处理文档解析。它的核心特…...