链表中等2 种解法
#24两两交换链表中的节点
不修改节点值,将单链表中每两个相邻节点交换。
#链表#递归#迭代
解题主线
01
哨兵节点让首对节点的交换与后续节点对使用同一套重连逻辑。
02
递归中第二个节点成为当前段新头,第一个节点连接已交换完成的后缀。
解法 1:迭代重连
让 previous 指向每一对节点的前驱,交换后移动到该对的新尾部。
时间复杂度
O(n)
空间复杂度
O(1)
java
final class ListNode {
int val;
ListNode next;
ListNode(int val) {
this.val = val;
}
ListNode(int val, ListNode next) {
this.val = val;
this.next = next;
}
}
final class Solution {
public ListNode swapPairs(ListNode head) {
ListNode dummy = new ListNode(0, head);
ListNode previous = dummy;
while (previous.next != null && previous.next.next != null) {
ListNode first = previous.next;
ListNode second = first.next;
first.next = second.next;
second.next = first;
previous.next = second;
previous = first;
}
return dummy.next;
}
}让 previous 指向每一对节点的前驱,交换后移动到该对的新尾部。
解法 2:递归交换
先递归交换第二个节点之后的链表,再翻转当前两个节点的连接。
时间复杂度
O(n)
空间复杂度
O(n),递归栈
java
final class ListNode {
int val;
ListNode next;
ListNode(int val) {
this.val = val;
}
ListNode(int val, ListNode next) {
this.val = val;
this.next = next;
}
}
final class Solution {
public ListNode swapPairs(ListNode head) {
if (head == null || head.next == null) return head;
ListNode second = head.next;
head.next = swapPairs(second.next);
second.next = head;
return second;
}
}先递归交换第二个节点之后的链表,再翻转当前两个节点的连接。
边界与易错点
- 重连前先保存两个节点引用,避免修改 next 后丢失后缀。
- 奇数长度链表的最后一个节点保持原位。
整理来源
由旧仓库源码复核、去重并整理;展示代码已按 Java 21 语义修正明显问题。
medium/Q024_swapPairs.java