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

[灵感源于算法] 链表类问题技巧总结

[灵感源于算法] 链表类问题技巧总结
@水墨不写bug


在这里插入图片描述


文章目录

  • 一、链表类题目实用技巧总结
    • 1. 动手画图的重要性
    • 2. 虚拟头节点技巧
    • 3. 多指针辅助技巧
    • 4. 快慢双指针技巧
  • 二、能力提升题目推荐
    • 1、leetcode [2. 两数相加(另一种意义上的大数相加)](https://leetcode.cn/problems/add-two-numbers/description/?envType=study-plan-v2&envId=top-100-liked)
    • 2、leetcode [25. K 个一组翻转链表](https://leetcode.cn/problems/reverse-nodes-in-k-group/description/?envType=study-plan-v2&envId=top-100-liked)
    • 3、leetcode [24. 两两交换链表中的节点](https://leetcode.cn/problems/swap-nodes-in-pairs/description/?envType=study-plan-v2&envId=top-100-liked)
  • 三、总结与建议


一、链表类题目实用技巧总结

1. 动手画图的重要性

  • 实用性:链表操作需要精确的指针操作,画图可避免逻辑错误,特别在处理复杂指针重定向时
  • 示例:反转链表(可视化指针变化)
ListNode* reverseList(ListNode* head) {ListNode *prev = nullptr;  // 前驱指针ListNode *curr = head;     // 当前指针while (curr) {// 画图示意:A->B->C 变为 A<-B  CListNode *next = curr->next;  // 临时保存下一个节点curr->next = prev;           // 反转指针方向prev = curr;                 // 前移prevcurr = next;                 // 前移curr}return prev;  // 新链表头
}

图解过程

初始: 1 → 2 → 3 → ∅
步骤1: ∅ ← 1  2 → 3 → ∅  (prev=1, curr=2)
步骤2: ∅ ← 1 ← 2  3 → ∅  (prev=2, curr=3)
最终: ∅ ← 1 ← 2 ← 3      (prev=3, curr=null)

优势:避免指针丢失错误,清晰展示每一步状态变化

2. 虚拟头节点技巧

  • 实用性:消除头节点特殊处理,统一操作逻辑,避免空指针异常
  • 示例:删除所有值为val的节点
ListNode* removeElements(ListNode* head, int val) {ListNode dummy(0);         // 创建虚拟头节点dummy.next = head;ListNode* curr = &dummy;   // 当前指针指向虚拟头while (curr->next) {if (curr->next->val == val) {ListNode* toDelete = curr->next;curr->next = curr->next->next;  // 跳过待删除节点delete toDelete;    // 释放内存} else {curr = curr->next;  // 正常后移}}return dummy.next;        // 返回真实头节点
}

优势对比

// 无虚拟头节点的实现(需要额外处理头节点)
ListNode* removeElements(ListNode* head, int val) {// 特殊处理头节点连续匹配的情况while (head && head->val == val) {ListNode* temp = head;head = head->next;delete temp;}if (!head) return nullptr;// 处理后续节点ListNode* curr = head;while (curr->next) {if (curr->next->val == val) {ListNode* temp = curr->next;curr->next = temp->next;delete temp;} else {curr = curr->next;}}return head;
}

优势:虚拟头节点统一了删除逻辑,代码更简洁,避免重复处理头节点

3. 多指针辅助技巧

  • 实用性:使用额外指针简化复杂操作,避免指针操作顺序错误
  • 示例:在排序链表中插入节点
ListNode* insertNode(ListNode* head, int val) {ListNode* newNode = new ListNode(val);// 情况1:插入到头节点前面if (!head || val < head->val) {newNode->next = head;return newNode;}// 使用双指针:prev跟踪前驱,curr遍历ListNode *prev = head;ListNode *curr = head->next;while (curr && curr->val < val) {prev = curr;curr = curr->next;}// 插入到prev和curr之间prev->next = newNode;newNode->next = curr;return head;
}

优势:使用prevcurr两个指针,避免在单指针方案中需要记住前驱节点的麻烦

4. 快慢双指针技巧

  • 实用性:解决链表中的位置关系问题,时间复杂度O(N),空间复杂度O(1)
  • 应用1:检测环形链表及环入口
ListNode *detectCycle(ListNode *head) {ListNode *slow = head, *fast = head;// 第一阶段:检测环是否存在while (fast && fast->next) {slow = slow->next;        // 慢指针走1步fast = fast->next->next;  // 快指针走2步if (slow == fast) break;  // 相遇说明有环}// 无环情况if (!fast || !fast->next) return nullptr;// 第二阶段:查找环入口slow = head;  // 慢指针重置到头while (slow != fast) {slow = slow->next;  // 两者同步前进fast = fast->next;}return slow;  // 相遇点即为环入口
}
  • 应用2:查找倒数第K个节点
ListNode* getKthFromEnd(ListNode* head, int k) {ListNode *fast = head, *slow = head;// fast先走k步for (int i = 0; i < k; ++i) {if (!fast) return nullptr; // 链表长度不足kfast = fast->next;}// 同步移动直到fast到达末尾while (fast) {slow = slow->next;fast = fast->next;}return slow;  // slow指向倒数第k个节点
}
  • 应用3:找到链表中点(奇数为中点,偶数为上中点)
ListNode* findMiddle(ListNode* head) {ListNode *slow = head, *fast = head;while (fast && fast->next && fast->next->next) {slow = slow->next;        // 慢指针走1步fast = fast->next->next;  // 快指针走2步}return slow;
}

二、能力提升题目推荐

1、leetcode 2. 两数相加(另一种意义上的大数相加)

逆序链表数字相加,其实逆序更加好做。

class Solution {
public:ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {ListNode* cur1 = l1,*cur2 = l2,*phead = new ListNode(0),*prev = phead;int t = 0;while(cur1 || cur2 || t){if(cur1){t += cur1->val;cur1 = cur1->next;}if(cur2){t += cur2->val;cur2 = cur2->next;}prev->next = new ListNode(t % 10);t /= 10;prev = prev->next;}ListNode* ret = phead->next;delete phead;return ret;}
};

2、leetcode 25. K 个一组翻转链表

有难度的一道题目,主要思想是:
先统计需要反转多少次,接下来进行
1、同时维护两个链表;
2、头插pcur,pcur再移动到尾部,重复循环头插

class Solution {
public:ListNode* reverseKGroup(ListNode* head, int k) {/*整体思路:K个一组进行头插,k个插完之后,pcur移动到末尾,再次循环进行k个一组进行头插最后不满k个一组的,不用改变链表的结构,放在后面直接链入最终结果链表*/ListNode* phead = new ListNode(-1),*cur = head,*pcur = phead;//pcur自己维护一个链表int count = 0;while(cur)//统计整体节点个数{++count;cur = cur->next;}int sp = count / k;//一共需要反转的轮数cur = head;//重置cur到head节点while(sp--){for(int i = 0;i < k;++i){ListNode* next = cur->next,*pnext = pcur->next;//p:表示pcur维护的答案链表pcur->next = cur;cur->next = pnext;cur = next;}while(pcur->next)pcur = pcur->next;}pcur->next = cur;//把剩余的部分接入答案链表中ListNode* ret = phead->next;delete phead;return ret;}
};

3、leetcode 24. 两两交换链表中的节点

其实就是上一题的k==2的特殊情况,但是针对这一题实现的逻辑会更加简单

class Solution {
public:ListNode* swapPairs(ListNode* head) {if(head == nullptr || head->next == nullptr)return head;ListNode* phead = new ListNode(0);//头节点,简化逻辑phead->next = head;ListNode* cur = head,*next = head->next,*prev = phead;while(cur && cur->next){cur->next = next->next;next->next = cur;prev->next = next;prev = cur;cur = cur->next;if(cur)next = cur->next;}cur = phead->next;delete phead;return cur;}
};

三、总结与建议

  1. 画图先行:在纸上画出初始状态、目标状态和中间步骤,特别是涉及多个指针的操作
  2. 虚拟头节点:当操作可能改变头节点时,优先考虑使用dummy node
  3. 多指针策略
    • 使用prev/curr处理插入/删除
    • 使用curr/next避免指针丢失
    • 复杂操作时创建临时指针保存关键节点
  4. 快慢指针应用场景
    • 环检测:快慢指针是否相遇
    • 环入口:相遇后重置慢指针
    • 中点查找:快指针到末尾时慢指针位置
    • 倒数第K个:快指针先走K步
    • 链表相交:双指针走不同路径

在这里插入图片描述

完~
未经作者同意禁止转载

相关文章:

  • Ubuntu 实现可视化组raid和升级raid
  • Git 介绍、安装以及基本操作
  • 【PhysUnits】17.7 readme.md更新
  • 仓库物资出入库管理系统源码+uniapp小程序
  • 大模型笔记_检索增强生成(RAG)
  • 在 Azure 机器学习中注册 MLflow 模型
  • 汉诺塔 (easy)
  • Spark提交流程
  • JAVA毕业设计227—基于SpringBoot+hadoop+spark+Vue的大数据房屋维修系统(源代码+数据库)
  • PHP:互联网时代的常青编程语言
  • C++ 中的 iostream 库:cin/cout 基本用法
  • 【JavaEE】-- HTTPS
  • windows电脑解决笔记本搜索不到wifi问题
  • 侃侃AI编程
  • javaee初阶-多线程
  • 电机专用32位MCU PY32MD310,QFN32封装,内置多功能栅极驱动器
  • 曼昆《经济学原理》第九版 第十六章垄断竞争
  • 免部署的数字人 API 调用教程:基于 wav2lip模型训练的开放API,附 PHP 代码示例
  • 大模型与人工智能
  • React Vue 编译/运行流程
  • 网站建设和网站设计一样吗/武汉推广系统
  • axcure做网站ui/软文范例200字
  • 上饶网站网站建设/百度知道合伙人
  • 德州网站建设维护/网络科技
  • 省级政府网站集约化建设/百度指数行业排行
  • wordpress 调用编辑器/seo博客网址