题目:给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。
提示:
-
链表中节点的数目在范围 [0, 100] 内
-
0 <= Node.val <= 100
这个题目比较简单,但要注意交换结点时,要先保存两个结点的值,再进行交换,不然会找不到结点。交换时还要注意交换代码的顺序。
算法步骤:
-
检查特殊情况:如果链表为空或只有一个节点,那么不需要交换,直接返回原链表的头节点。
-
创建虚拟头节点:为了避免在交换头节点时的特殊情况处理,我们可以创建一个虚拟头节点 dummyHead,它的 next 指向原链表的头节点。
-
遍历链表:使用一个循环来遍历链表,每次交换一对相邻的节点。
-
交换节点:对于每一对相邻的节点,调整它们的 next 指针来完成交换。
-
更新指针:在交换后,更新 p 指针到新的后一个节点,以便进行下一对节点的交换。
-
返回结果:返回虚拟头节点的下一个节点,即交换后的链表的头节点。
复杂度分析:
-
时间复杂度: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;}
}