当前位置: 首页 > 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.gsyq.cn/news/1508569.html

相关文章:

  • Keil MDK专用ARM Compiler 5.06 for Windows(32位ARM Cortex-M/R/A裸机开发)
  • 多维数据聚合实战:Pandas高维groupby性能与稳定性优化
  • LangChain中文文档切分实战:语义完整性与向量检索优化指南
  • 2026免费一键去图片水印的app推荐,免费去图片水印app排行榜
  • Python 高手编程系列三千四百:何时应该使用多线程
  • Flask生产部署指南:Heroku上线避坑与Gunicorn配置
  • 2026年音乐喷泉行业深度观察:专业公司如何选择?从设计到落地全流程解析 - 优质品牌商家
  • 数据粒度设计五大陷阱与七步落地法
  • 哪家的天地盖包装盒比较靠谱? - 工业推荐榜
  • Prometheus 多集群联邦与 Thanos 长期存储:从单集群到全局监控
  • Python 高手编程系列三千三百九十九:为什么需要并发
  • Matplotlib底层原理与工程化实践指南
  • 2026年必看:会计方面的证书都有哪些?财务岗系统提升路径与数据驱动能力全解析
  • 2026乐山临江鳝丝实测指南:哪家店值得专程打卡?非遗技艺与市井烟火的终极对决 - 优质品牌商家
  • 2026年山东油水分离器源头厂家深度解析:哪家技术更成熟?附真实案例与采购指南 - 优质品牌商家
  • 老旧小区物业团购模式的数智化技术落地实践
  • 生产级多维聚合:一次groupby搞定可解释、可落地的分析口径
  • 2026年银川合同律师哪家好?5位实战经验丰富值得信赖推荐 - 本地品牌推荐
  • 成都企云讯灵 geo 口碑怎么样? - 工业推荐榜
  • R语言中ANOVA与ANCOVA实战:从方差分解到协变量校准
  • VideoDownloadHelper:Chrome视频下载插件终极使用指南
  • 2026年成都国际国内货物运输代理服务格局观察:本土企业的差异化竞争力与行业趋势 - 优质品牌商家
  • C# WinForms项目直接调用C++开发的OCX控件实操包(含注册配置与调试工程)
  • Linux 10 防火墙
  • 避开各类安装坑!OpenClaw 双系统稳定部署实战
  • 2026年6月国内比较好的线上获客品牌推荐,门窗线上获客/门窗定制抖音投流获客,线上获客品牌哪家权威 - 品牌推荐师
  • 2026年靠谱的苏州净化工程公司/恒温恒湿净化工程/苏州化妆品无尘室净化工程口碑好的厂家推荐 - 行业平台推荐
  • 2026年汽车清洗液市场口碑观察:哪些品牌与产品值得关注? - 优质品牌商家
  • 别只看机械键盘!聊聊罗技MX Keys的‘薄膜美学’:静音、轻薄与剪刀脚结构的独特魅力
  • 2026年腾讯邮箱服务公司,哪个口碑好 - myqiye