24. 两两交换链表中的节点
24. 两两交换链表中的节点
#### 双指针
思路
指针pre、cur遍历链表,每次循环分别指向两个相邻的结点。指针link、tmp辅助实现两两交换。每次交换指针操作次数过多,较复杂,画图避免出错。
class Solution {
public ListNode swapPairs(ListNode head) {
if (head == null || head.next == null) {
return head;
}
ListNode dummy = new ListNode(-1); // 虚拟头结点
dummy.next = head;
ListNode pre = head;
ListNode cur = head.next;
ListNode tmp = null;
ListNode link = dummy; // 前一对结点的第二个结点,用于连接当前对结点
while (cur != null && cur.next != null) {
tmp = cur.next;
cur.next = pre;
link.next = pre.next;
pre.next = tmp;
link = pre;
pre = tmp;
cur = tmp.next;
}
return dummy.next;
}
}
递归
思路
一个原问题可以转化为规模变小的子问题,没有其他变化,只有问题规模变小,可尝试用递归解决,实现相对简单,理解困难。
注意递归出口的情况不能少、不能多,递归体的关键是在解决子问题的基础上进一步解决原问题。
class Solution {
// 返回链表结点交换后的头结点
public ListNode swapPairs(ListNode head) {
// 递归出口
if (head == null || head.next == null) return head;
// 递归体
ListNode next = head.next; // head 指向第一个结点,next 指向第二个结点
ListNode newNode = swapPairs(next.next);
next.next = head;
head.next = newNode;
return next;
}
}