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

ini
输入: head = [1,2,3,4]
输出: [2,1,4,3]
示例 2:
ini
输入: head = []
输出: []
示例 3:
ini
输入: head = [1]
输出: [1]
提示:
- 链表中节点的数目在范围
[0, 100]内 0 <= Node.val <= 100
思路:
建议使用虚拟头结点,这样会方便很多,要不然每次针对头结点(没有前一个指针指向头结点),还要单独处理。
接下来就是交换相邻两个元素了,此时一定要画图,不画图,操作多个指针很容易乱,而且要操作的先后顺序
初始时,cur指向虚拟头结点,然后进行如下三步:

操作之后,链表如下:

看这个可能就更直观一些了:

解题:
C语言版:
c
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* swapPairs(struct ListNode* head) {
struct ListNode dummy = {0, head}; // 用哨兵节点简化代码逻辑
struct ListNode* node0 = &dummy;
struct ListNode* node1 = head;
while (node1 && node1->next) { // 至少有两个节点
struct ListNode* node2 = node1->next;
struct ListNode* node3 = node2->next;
node0->next = node2; // 0 -> 2
node2->next = node1; // 2 -> 1
node1->next = node3; // 1 -> 3
node0 = node1; // 下一轮交换,0 是 1
node1 = node3; // 下一轮交换,1 是 3
}
return dummy.next; // 返回新链表的头节点
}