题目描述
给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。 要求:不能修改结点内部 val 值,只能调整指针交换节点。
示例: 输入链表:1 → 2 → 3 → 4 输出链表:2 → 1 → 4 → 3
如果链表节点总数为奇数,最后一个节点无需交换。
解题思路
核心难点
- 链表头节点会发生变化,需要统一处理头部交换逻辑;
- 两两交换节点时,要维护交换节点前驱节点的指针,否则链表断裂;
- 禁止修改节点内数值,仅允许操作指针。
技巧:虚拟头结点(哑节点 dummy)
手动创建一个不存储有效数据的虚拟节点 newhead,让 newhead->next = head。 好处:原始头节点和普通节点交换逻辑完全一致,不需要单独写 if 特殊处理头部。
指针规划
prev:待交换两个节点的前驱节点cur:待交换第一个节点next:待交换第二个节点nnext:下一组链表起始节点(保存防止断链)
交换前形态: prev → cur → next → nnext
交换目标形态: prev → next → cur → nnext
交换步骤:
cur->next = nnextcur 接上后续链表next->next = curnext 指向 cur,完成两节点翻转prev->next = next前驱节点指向新的头部 nextprev = curprev 移动到下一组前驱位置,开启下一轮循环
循环终止条件:prev->next == nullptr || prev->next->next == nullptr 后面不足两个节点,无需继续交换。
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* prev,*cur ,*next,*nnext;
ListNode* newhead=new ListNode(0);
newhead->next=head;
prev=newhead;
while(prev->next != nullptr && prev->next->next != nullptr)
{ // 1 2 3 4
//prev cur,next nnext
cur=prev->next;
next=cur->next;
nnext=next->next;
cur->next=nnext;
next->next=cur;
prev->next=next;
prev=cur;
}
return newhead->next;
}
};