
📒 链表常用技巧与操作总结
一、 链表解题4大通用技巧
- 画图辅助:指针反转/交换时必画图,避免指向关系混乱。
- 虚拟头节点:引入不带数据的虚拟头节点(Dummy Node),统一处理空指针和头节点修改的边界问题。
- 大胆定义变量:不吝啬空间,按需定义前驱(pre)、尾指针(tail)、快慢双指针等。
- 快慢双指针应用 :
- 找链表中点、倒数第N个节点。
- 判断链表是否有环(相遇则有环)。
- 找环的入口(相遇后,慢指针回起点,快慢同速走,再次相遇点即入口)。
二、 重点题型:链表两数相加(LeetCode 2)
核心思路:模拟竖式加法,逐位相加并维护进位。
- 逆序存储(默认情况) :
- 链表头是个位,直接从头遍历相加。
- 维护进位变量
carry(笔记中的t)。 - 任意链表未遍历完 或 还有剩余进位时,继续循环。
- 正序存储(进阶情况) :
- 需要逆序操作,通常配合栈(Stack)或递归实现。
三、 链表两数相加(逆序)代码模板
class ListNode {
int val;
ListNode next;
ListNode(int val) { this.val = val; }
}
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
// 1. 创建虚拟头节点(对应笔记中的 newHead)
ListNode dummy = new ListNode(0);
ListNode resCur = dummy; // 结果链表的移动指针
int carry = 0; // 进位标记(对应笔记中的 t)
// 2. 循环条件:链表未遍历完 或 还有进位
while (l1 != null || l2 != null || carry != 0) {
// 3. 取值:链表为空则补0
int v1 = (l1 != null) ? l1.val : 0;
int v2 = (l2 != null) ? l2.val : 0;
// 4. 计算总和与进位
int sum = v1 + v2 + carry;
resCur.next = new ListNode(sum % 10); // 当前位结果
carry = sum / 10; // 更新进位
// 5. 指针后移
resCur = resCur.next;
if (l1 != null) l1 = l1.next;
if (l2 != null) l2 = l2.next;
}
// 6. 返回虚拟头的下一个节点
return dummy.next;
}
四、 补充:其他链表高频操作备忘
- 反转链表 :定义
pre = null,cur = head,遍历改指向

- 合并链表:虚拟头节点 + 双指针比较大小尾插。
- 删除倒数第N个节点:快指针先走N步,快慢同速走,快到尾时慢指针指向待删节点的前驱。