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;}
}