Skip to content

链表 ​

链表题的核心是指针操作与边界处理。先写清函数契约:输入代表什么、返回什么、谁拥有节点、是否允许修改结构;再处理空节点和单节点。

Dummy Node ​

涉及删除头节点、合并或分段拼接时,使用栈上的 dummy node 可统一边界:

cpp
ListNode dummy{0, head};
ListNode* prev = &dummy;
// 修改 prev->next
return dummy.next;

不要为仅作哨兵的节点 new 后忘记释放。在线评测返回的新链表节点是否由调用方释放取决于题目约定;工程代码优先使用 RAII 所有权。

反转链表 ​

迭代法 O(n) 时间、O(1) 额外空间,避免深链表递归导致栈溢出:

cpp
ListNode* reverse(ListNode* head) {
    ListNode* previous = nullptr;
    while (head) {
        ListNode* next = head->next;
        head->next = previous;
        previous = head;
        head = next;
    }
    return previous;
}

反转区间、K 个一组反转的关键是保留区间前驱、区间首节点(反转后变尾)与区间后继,再安全地重新连接。

快慢指针 ​

cpp
while (fast && fast->next) {
    slow = slow->next;
    fast = fast->next->next;
}

常见用途:

  • 找中点:奇数长度时 slow 落在中点,偶数时落在后半段起点;
  • 判断环:快慢指针相遇说明有环;
  • 找环入口:相遇后,一个指针回到头部,二者同速前进,再次相遇即入口;
  • 回文链表:找中点、反转后半段、逐项比较;若题目要求保持原链表,应再反转恢复。

两链表相交 ​

让指针 A 走 A 再走 B,指针 B 走 B 再走 A;相交则在交点相遇,不相交则同时变为 nullptr。它比较的是节点地址而非节点值,时间 O(m+n)、空间 O(1)。

关联笔记 ​

使用 Markdown 与 VitePress 构建