力扣题目解析--两两交换链表中的节点

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

示例 1:

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

示例 2:

复制代码
输入:head = []
输出:[]

示例 3:

复制代码
输入:head = [1]
输出:[1]

提示:

  • 链表中节点的数目在范围 [0, 100]
  • 0 <= Node.val <= 100

代码展示

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 dummy(0);
        dummy.next=head;
        ListNode *prev=&dummy;

        while(prev->next!=nullptr&&prev->next->next!=nullptr){
            ListNode*first=prev->next;
            ListNode*second=prev->next->next;
            first->next=second->next;
            second->next=first;
            prev->next=second;
            prev=first;
        }
        return dummy.next;


    }
};

写者心得

这段代码有几个难点,首先就是那个虚拟头节点的设置,ListNode *prev=&dummy;这一步和往常的虚拟头节点设置是不一样的,因为我们后续需要把两个链表中的元素进行交换,而这一步是真正这个题目的核心一步,如果没有这一步,按着这个循环,就会把相邻的元素进行交换变成把链表颠倒过来,所以设置一个前置节点,再进行交换,就可以达成相邻元素进行交换。还有一个就是prev=first;其实都是为了达成相邻元素进行交换这个目的,这个就相当于是跳过目前已经交换的元素

代码的逐行解释

复制代码
class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        // 创建一个虚拟头节点(dummy node),它的值为0。
        // 这个节点的存在是为了简化处理逻辑,特别是当原始链表的头节点也需要被交换时。
        ListNode dummy(0);
        
        // 让虚拟头节点的 next 指向原始链表的头节点。
        // 这样一来,即使原始链表的头节点发生变化,我们也可以通过 dummy.next 来访问新的头节点。
        dummy.next = head;
        
        // 创建一个指针 prev,它指向虚拟头节点。
        // prev 用于追踪当前要交换的两个节点对之前的节点。
        ListNode *prev = &dummy;

        // 使用 while 循环遍历链表,直到没有足够的节点可以进行交换。
        // 条件检查确保至少有两个节点可以交换:prev->next 和 prev->next->next 都不为空。
        while (prev->next != nullptr && prev->next->next != nullptr) {
            // 初始化 first 指针,指向当前要交换的第一个节点(即 prev 后面的第一个节点)。
            ListNode *first = prev->next;
            
            // 初始化 second 指针,指向当前要交换的第二个节点(即 first 的下一个节点)。
            ListNode *second = prev->next->next;

            // 让 first 指向原本 second 之后的节点。
            // 这一步是准备将 first 和 second 的位置交换,同时保证链表不会断裂。
            first->next = second->next;
            
            // 将 second 的 next 指向 first,完成这两个节点的位置交换。
            second->next = first;
            
            // 更新 prev 的 next 指针,使其指向新的头部节点(即 second),以反映交换后的链表结构。
            prev->next = second;
            
            // 移动 prev 指针到刚刚交换过的两个节点中的后一个节点(即原来的 first),以便为下一次迭代做准备。
            prev = first;
        }

        // 返回新的链表头节点,即虚拟头节点的 next 指针所指向的节点。
        return dummy.next;
    }
};
相关推荐
熬了夜的程序员17 小时前
【LeetCode】83. 删除排序链表中的重复元素
算法·leetcode·链表
胖咕噜的稞达鸭17 小时前
AVL树手撕,超详细图文详解
c语言·开发语言·数据结构·c++·算法·visual studio
YSRM18 小时前
Leetcode+Java+图论II
java·leetcode·图论
熊猫钓鱼>_>18 小时前
Rust语言特性深度解析:所有权、生命周期与模式匹配之我见
算法·rust·软件开发·函数·模式匹配·异步编程·质量工具
芒果量化18 小时前
Optuna - 自动调参利器&python实例
开发语言·python·算法·机器学习
麦麦大数据18 小时前
D025 摩托车推荐价格预测可视化系统|推荐算法|机器学习|预测算法|用户画像与数据分析
mysql·算法·机器学习·django·vue·推荐算法·价格预测
CoovallyAIHub18 小时前
IDEA研究院发布Rex-Omni:3B参数MLLM重塑目标检测,零样本性能超越DINO
深度学习·算法·计算机视觉
豐儀麟阁贵19 小时前
4.4数组的基本操作
java·开发语言·数据结构·算法
无限进步_19 小时前
【C语言】在矩阵中高效查找数字的算法解析
c语言·开发语言·数据结构·c++·其他·算法·矩阵
小白要加油努力19 小时前
滑动窗口的典例以及思路阐述
算法