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;
    }
}
posted @ 2025-10-17 20:16  Nickey103  阅读(4)  评论(0)    收藏  举报