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

【算法题攻略】链表

文章目录

  • 一、习题讲解
    • 1. 两两交换链表中的节点(medium)
    • 2. 重排链表(medium)
    • 3. 合并 K 个升序链表(hard)
  • 二、练习题
    • 1. K个⼀组翻转链表(hard)

一、习题讲解

1. 两两交换链表中的节点(medium)

24. 两两交换链表中的节点

  • 题目描述:

给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。

示例 1:

  • 输入:head = [1,2,3,4]
  • 输出:[2,1,4,3]

示例 2:

  • 输入:head = [ ]
  • 输出:[ ]

示例 3:

  • 输入:head = [1]
  • 输出:[1]

提示:

  • 链表中节点的数目在范围 [0, 100] 内
  • 0 <= Node.val <= 100

  • 代码示例:
classSolution{public:ListNode*swapPairs(ListNode*head){if(head==nullptr||head->next==nullptr)returnhead;ListNode*phead=head;ListNode*cur=phead;ListNode*prev=phead->next;head=prev;// 换位后,头节点的位置也会变,提前设置好新的头节点位置phead=prev->next;while(cur&&prev){if(phead&&phead->next!=nullptr){prev->next=cur;cur->next=phead->next;cur=phead;prev=phead->next;phead=prev->next;}else{prev->next=cur;cur->next=phead;break;}}returnhead;}};

2. 重排链表(medium)

143. 重排链表

  • 题目描述:

给定一个单链表 L 的头节点 head ,单链表 L 表示为:

L0 → L1 → … → Ln - 1 → Ln

请将其重新排列后变为:

L0 → Ln → L1 → Ln - 1 → L2 → Ln - 2 → …

不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。

示例 1:

  • 输入:head = [1,2,3,4]
  • 输出:[1,4,2,3]

示例 2:

  • 输入:head = [1,2,3,4,5]
  • 输出:[1,5,2,4,3]

  • 代码示例:
classSolution{public:voidreorderList(ListNode*head){// 第一步:快慢指针找中间节点ListNode*mid=head;ListNode*prev=head;while(prev->next!=nullptr){prev=prev->next;if(prev->next!=nullptr)prev=prev->next;mid=mid->next;}if(mid==nullptr||mid->next==nullptr)// 链表节点小于3,无需重排return;// 第二步:对中间节点往后的节点进行逆序ListNode*left=mid;ListNode*right=mid->next;while(right){ListNode*tmp=right->next;right->next=left;left=right;right=tmp;}// 第三步:以phead 和 prev两个节点为起点,调整链表ListNode*phead=head;while((phead!=mid)&&(prev!=mid)){ListNode*tmp=phead->next;phead->next=prev;phead=tmp;tmp=prev->next;prev->next=phead;prev=tmp;}mid->next=nullptr;}};

3. 合并 K 个升序链表(hard)

23. 合并 K 个升序链表

  • 题目描述:

给你一个链表数组,每个链表都已经按升序排列。

请你将所有链表合并到一个升序链表中,返回合并后的链表。

示例 1:

  • 输入:lists = [ [1,4,5],[1,3,4],[2,6] ]
  • 输出:[1,1,2,3,4,4,5,6]
  • 解释:链表数组如下:
    [
    1->4->5,
    1->3->4,
    2->6
    ]
    将它们合并到⼀个有序链表中得到:1->1->2->3->4->4->5->6

示例 2:

  • 输入:lists = [ ]
  • 输出:[ ]

示例 3:

  • 输入:lists = [ [ ] ]
  • 输出:[ ]

提示:

  • k == lists.length
  • 0 <= k <= 10^4
  • 0 <= lists[i].length <= 500
  • -10^4 <= lists[i][j] <= 10^4
  • lists[i] 按 升序 排列
  • lists[i].length 的总和不超过 10^4

  • 代码演示:
classSolution{public:structgreater{booloperator()(constListNode*left,constListNode*right){return(left->val)>(right->val);}};ListNode*mergeKLists(vector<ListNode*>&lists){ListNode*head=nullptr;// 小堆,存储节点指针,自定义仿函数(比较节点的val)priority_queue<ListNode*,vector<ListNode*>,greater>pri1;// 将链表数组下,每个链表不为空的头节点加入小堆for(autoit:lists){if(it!=nullptr){pri1.push(it);}}ListNode*cur=nullptr;while(!pri1.empty()){ListNode*tmp=pri1.top();pri1.pop();if(tmp->next!=nullptr)pri1.push(tmp->next);if(head==nullptr){head=tmp;cur=tmp;}>这里是引用else{cur->next=tmp;cur=tmp;}}returnhead;}};

二、练习题

1. K个⼀组翻转链表(hard)

25. K 个一组翻转链表

  • 题目描述:

给你链表的头节点 head ,每 k 个节点一组进行翻转,请你返回修改后的链表。

k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。

你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。

示例 1:

  • 输入:head = [1,2,3,4,5], k = 2
  • 输出:[2,1,4,3,5]

示例 2:

  • 输入:head = [1,2,3,4,5], k = 3
  • 输出:[3,2,1,4,5]

示例 3:

  • 输入:lists = [ [ ] ]
  • 输出:[ ]

提示

  • 链表中的节点数目为 n
  • 1 <= k <= n <= 5000
  • 0 <= Node.val <= 1000
  • 解决链表相关的题目一定要画图!!!
  • 代码演示:
classSolution{public:voidreverse(ListNode*left,ListNode*right){ListNode*cur=nullptr;ListNode*prev=nullptr;cur=left->next;if(cur!=right)prev=cur->next;while(left!=right){cur->next=left;left=cur;cur=prev;if(cur&&cur!=right)prev=cur->next;}}ListNode*reverseKGroup(ListNode*head,intk){if(k==1)returnhead;ListNode*phead=head;ListNode*left=nullptr;ListNode*right=nullptr;ListNode*tail=nullptr;head=nullptr;while(phead!=nullptr){left=phead;// 以 k个节点为一组子链表( left指向子链表头节点,right指向子链表尾节点 )right=phead;inti=1;for(;i<k;i++){if(right->next!=nullptr)right=right->next;elsebreak;}if(i!=k)break;phead=right->next;// 记录下一次子链表的起点指针if(head==nullptr)head=right;reverse(left,right);// 对子链表进行翻转left->next=phead;if(tail==nullptr)tail=left;// 记录这一次 子链表的尾节点指针else{tail->next=right;tail=left;}}if(head==nullptr)head==phead;returnhead;}};

http://www.jsqmd.com/news/996801/

相关文章:

  • 185. ADB/Fastboot工具链实战|完整刷机流程拆解、分区刷写命令深度解析
  • 从理论到代码:深入理解高斯求积公式的MATLAB实现,附赠Legendre多项式生成脚本
  • 告别RGB软件混乱:OpenRGB统一控制你的所有灯光设备
  • 多维数据聚合实战:Pandas高维groupby性能与稳定性优化
  • 十九. 多线程
  • 2026年成都法拍房机构口碑观察:哪些服务商值得关注? - 优质品牌商家
  • MLOps实战:构建可审计、可观测、可伸缩的生产级模型服务
  • 生产级LLM智能体工程实践:工具调用、记忆机制与多模态融合
  • Rust 异步编程:smol 与 Tokio 运行时架构对比与选型决策
  • Halcon 3D点云处理实战:用get_object_model_3d_params()提取关键特征,实现自动化尺寸测量
  • LangChain中文文档切分实战:语义完整性与向量检索优化指南
  • YOLOv5人脸检测完整工程包:支持WIDER FACE训练、多格式导出与批量检测
  • 告别理想模型:用CGH40010F在ADS里手把手搭建一个更真实的Doherty功放(附工程文件)
  • 2026免费一键去图片水印的app推荐,免费去图片水印app排行榜
  • 2026年成都防水公司口碑与服务质量综合观察:哪些品牌值得关注? - 优质品牌商家
  • Python多线程与多进程选型指南:I/O密集用线程,CPU密集用进程
  • Windows全版本兼容的CPU与内存实时监控VC++工程(含MFC界面源码)
  • AI 推理性能调优:Speculative Decoding 投机解码的工程实践
  • 实战-day02
  • 2026年成都中小企业获客geo服务商费用排名 - 工业品牌热点
  • OpCore-Simplify:告别黑苹果配置噩梦,15分钟构建完美EFI的智能方案
  • 2026年音乐喷泉行业深度观察:专业公司如何选择?从设计到落地全流程解析 - 优质品牌商家
  • 医学影像特征提取技术:从统计方法到深度学习
  • Flask生产部署指南:Heroku上线避坑与Gunicorn配置
  • Python 高手编程系列三千四百:何时应该使用多线程
  • 分支限界法实战:从TSP到工业优化的可调试最优解实现
  • 数据粒度设计五大陷阱与七步落地法
  • 不同喀斯特地貌类型下土壤侵蚀影响因子的交互作用——以贵州省为例
  • 2026年电磁流量计厂商综合实力评估:技术、服务与项目适配度分析 - 优质品牌商家
  • 哪家的天地盖包装盒比较靠谱? - 工业推荐榜