迭代
class Solution {
public ListNode swapPairs(ListNode head) {
// 前置节点
ListNode prev = null;
// 交换左节点
ListNode curr = head;
// 前一个条件作用于 head 为空和节点数为偶数,后一个条件作用于节点数为奇数
while(curr != null && curr.next != null){
// 交换右节点
ListNode next = curr.next;
if(prev != null){ // 不是最前面两个节点则修改指向为 next.next
prev.next = next;
} else { // prev 为空说明交换的链表最前面两个节点,需要把返回的头节点指向交换右节点
head = head.next;
}
// 交换左右节点
curr.next = next.next;
next.next = curr;
// 交换后的左节点作为 prev
prev = curr;
curr = curr.next;
}
return head;
}
}
先思考两个需要交换的结点在中间时要怎么交换,在考虑边界条件
- 空间复杂度:O(1)
- 时间复杂度:O(n)
递归
class Solution {
public ListNode swapPairs(ListNode head) {
if(head == null || head.next == null) return head;
// 交换以两个节点为单位,即获取的是头结点 next.next
ListNode p = swapPairs(head.next.next);
// 交换左右两个节点
ListNode next = head.next;
head.next = p;
next.next = head;
// 修改头结点到正确位置
head = next;
return head;
}
}
第一次没看题解写出递归写法
先考虑好递归终止条件,即最小子问题是什么,这里是 head 为空或 head 是最后一个结点,直接返回 head
下面是先调用方法获取两个节点后面的头节点,然后交换两个节点,最后修改头结点返回
- 空间复杂度:O(n)
- 时间复杂度:O(n)
虚拟头结点迭代
class Solution {
public ListNode swapPairs(ListNode head) {
// 虚拟头结点
ListNode node = new ListNode(0, head);
// 暂存结点,交换完成后返回 temp.next
ListNode temp = node;
while(node.next != null && node.next.next != null){
// 交换左节点
ListNode left = node.next;
ListNode right = node.next.next;
node.next = right;
left.next = right.next;
right.next = left;
node = left;
}
return temp.next;
}
}
题解的迭代做法
- 空间复杂度:O(1)
- 时间复杂度:O(n)