题目
示例
示例 1:
输入:head = [1,2,3,4] 输出:[2,1,4,3]
示例 2:
输入:head = [] 输出:[]
示例 3:
输入:head = [1] 输出:[1]
思想(虚拟头节点)
算法分析与设计
使用虚拟头节点: 创建一个虚拟头节点 dummy
,并将其指向原始链表的头部。
ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode prev = dummy;
循环遍历: 使用 while
循环遍历链表,确保至少有两个节点需要交换。循环条件为 head != null && head.next != null
。
定义指针: 在循环内,定义两个指针 p
和 q
分别指向当前要交换的两个节点。
ListNode p = head;
ListNode q = head.next;
交换节点: 交换 p
和 q
节点,同时更新相关的 next
指针。
p.next = q.next;
q.next = p;
prev.next = q;
更新指针: 更新 prev
和 head
指针,准备进行下一次交换。
prev = p;
head = p.next;
循环结束: 循环结束后,返回虚拟头节点的 next
,即交换后的链表头。
总体思路: 通过不断地交换相邻的两个节点,每次更新指针来保持链表的正确连接关系。在循环中,每次交换两个节点后,更新 prev
、head
指针,确保下一次循环能够正确处理相邻的节点。循环结束后,返回虚拟头节点的 next
,即交换后的链表头。
代码实现
class Solution {
public ListNode swapPairs(ListNode head) {
if (head == null || head.next == null) {
return head; // 如果链表为空或只有一个节点,无需交换
}
ListNode dummy = new ListNode(0); // 创建一个虚拟头节点
dummy.next = head;
ListNode prev = dummy;
while (head != null && head.next != null) {
ListNode p = head;
ListNode q = head.next;
// 交换节点
p.next = q.next;
q.next = p;
prev.next = q;
// 更新prev和head
prev = p;
head = p.next;
}
return dummy.next;
}
}