LeetCode 24.两两交换链表中的节点:虚拟头结点与指针

1. 题目描述(题目链接)

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

示例:

复制代码
输入:head = [1, 2, 3, 4]
输出:[2, 1, 4, 3]

2. 核心算法思想:虚拟头结点 + 迭代

由于交换操作会改变链表的头节点(例如原链表 1->2 交换后头节点变为 2),为了统一处理逻辑,避免对头节点进行特殊判断,我们引入虚拟头结点(Dummy Node)。

算法步骤:

1.创建一个虚拟头结点 dummyHead,令 dummyHead->next = head。

2.定义一个遍历指针 cur,初始指向 dummyHead。

3.进入循环,循环条件为 cur 后面至少存在两个节点(即 cur->next 和 cur->next->next 均不为空)。

4.在循环内部,定义 node1 = cur->next 和 node2 = cur->next->next,通过三步指针重定向完成交换:

  • cur->next 指向 node2
  • node1->next 指向 node2->next
  • node2->next 指向 node1

5.将 cur 移动至 node1 的位置,准备处理下一对节点。

6.循环结束后,返回 dummyHead->next(即新的头节点)。

3. 代码实现 (C++)

cpp 复制代码
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        // 创建虚拟头结点,统一处理头节点交换的情况
        ListNode* dummyHead = new ListNode(0);
        dummyHead->next = head;
        
        // cur 指针用于遍历链表,初始指向虚拟头结点
        ListNode* cur = dummyHead;
        
        // 只有当 cur 后面有两个节点时,才进行交换
        while (cur->next != nullptr && cur->next->next != nullptr) {
            ListNode* node1 = cur->next;       // 第一个节点
            ListNode* node2 = cur->next->next; // 第二个节点
            
            // 核心指针交换逻辑 (建议画图辅助理解)
            cur->next = node2;                 // 步骤1:cur 指向第二个节点
            node1->next = node2->next;         // 步骤2:第一个节点指向第二个节点的后继
            node2->next = node1;               // 步骤3:第二个节点指向第一个节点(完成交换)
            
            // 将 cur 移动到下一对要交换节点的前一个位置
            cur = node1;
        }
        
        // 获取新的头节点并释放虚拟头结点内存
        ListNode* result = dummyHead->next;
        delete dummyHead; 
        return result;
    }
};

4. 复杂度分析

时间复杂度:O(N) 。其中 N为链表的节点数量。我们需要遍历链表中的每一个节点,且每个节点只被操作常数次。

空间复杂度:O(1)。算法只使用了常数个额外的指针变量(dummyHead, cur, node1, node2),没有递归调用栈的开销,也没有开辟新的数组空间。

相关推荐
dialect_1 天前
KMP算法
开发语言·c++·算法
reikocao1 天前
卡尔曼滤波的动态机制:P如何改变融合权重
算法
漂流瓶jz1 天前
UVA-1612 猜名次 题解答案代码 算法竞赛入门经典第二版
数据结构·算法·题解·排序·aoapc·算法竞赛入门经典
吞下星星的少年·-·1 天前
Div.2 CF 1130B题(构造,贪心)
算法·贪心·构造
文丑颜不良啊1 天前
LeetCode1481~1500题目解析
java·leetcode
文丑颜不良啊1 天前
LeetCode1381~1400题目解析
java·leetcode
是main不是漫1 天前
【双指针——移动零】数组划分类题目的入门基石
c++·算法
深圳市快瞳科技有限公司1 天前
野外鸟类AI识别落地实录:输入适配、结构化输出、去重聚合与置信度分流的工程实践
算法·计算机视觉·鸟类识别·鸟类ai识别·野外鸟类观测·林业调查
专注仿真1 天前
梯度提升类(XFBoost)算法详解与代码实例
开发语言·人工智能·python·算法·大模型训练·控制算法
小豆庄1 天前
视频遮罩追踪退场后ID撞号的排查—多目标场景下的失效
opencv·算法·bug·视频·python3.11