【LeetCode 24】力扣算法:两两交换链表中的节点

题目:给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。

提示:

  • 链表中节点的数目在范围 [0, 100] 内

  • 0 <= Node.val <= 100

image


这个题目比较简单,但要注意交换结点时,要先保存两个结点的值,再进行交换,不然会找不到结点。交换时还要注意交换代码的顺序。

算法步骤:

  1. 检查特殊情况:如果链表为空或只有一个节点,那么不需要交换,直接返回原链表的头节点。

  2. 创建虚拟头节点:为了避免在交换头节点时的特殊情况处理,我们可以创建一个虚拟头节点 dummyHead,它的 next 指向原链表的头节点。

  3. 遍历链表:使用一个循环来遍历链表,每次交换一对相邻的节点。

  4. 交换节点:对于每一对相邻的节点,调整它们的 next 指针来完成交换。

  5. 更新指针:在交换后,更新 p 指针到新的后一个节点,以便进行下一对节点的交换。

  6. 返回结果:返回虚拟头节点的下一个节点,即交换后的链表的头节点。

复杂度分析:

  • 时间复杂度:O (n),其中 n 是链表的长度。最多遍历链表一次。

  • 空间复杂度:O (1),我们只使用了常数级别的额外空间。

我的 Java 代码:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode swapPairs(ListNode head) {
        // 处理特殊链表
        if(head==null)      return null;
        if(head.next==null) return head;
        
        // 创建虚拟头节点
        ListNode dummyHead = new ListNode(-1);
        dummyHead.next = head;
        ListNode p = dummyHead;
        
        // 遍历链表,交换每一对相邻的节点(当前p结点的后面两个结点)
        while(p.next!=null && p.next.next!=null){
            ListNode f = p.next;       //存储第一个结点
            ListNode s = p.next.next;  //存储第二个结点
            // 交换两个节点,先后顺序不能乱
            p.next = s;
            f.next = s.next;
            s.next = f;
            // 指针向后移动 两个 结点
            p = p.next.next;
        }
        return dummyHead.next;
    }
}
posted @ 2025-07-29 18:00  junjunyi  阅读(12)  评论(0)    收藏  举报