题目描述
给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。
示例 1:
输入:head = [1,2,3,4] 输出:[2,1,4,3]示例 2:输入:head = [] 输出:[]
示例 3:输入:head = [1] 输出:[1]
提示:
- 链表中节点的数目在范围
[0, 100]
内0 <= Node.val <= 100
解题思路
要实现两两交换链表中的相邻节点,可以使用迭代的方法,借助指针操作来完成节点的交换。这里我们不修改节点的值,只通过调整节点之间的连接顺序来达到目的。
-
使用虚拟头节点:为了方便处理链表头节点的特殊情况,我们可以创建一个虚拟头节点
dummy
,其next
指向原链表的头节点。 -
迭代交换节点:我们使用三个指针
prev
、first
和second
来指向要交换的节点及其前驱节点;通过调整指针的连接顺序来交换first
和second
节点的位置;然后将prev
移动到first
的位置,继续处理下一个节点对。 -
返回新头节点:最后返回
dummy.next
作为新的头节点。
复杂度分析
- 时间复杂度O(n): 其中
n
是链表的节点数。我们只遍历了一次链表。 - 空间复杂度O(1): 只使用了常数个指针。
代码实现
package org.zyf.javabasic.letcode.hot100.list;
import org.zyf.javabasic.letcode.list.base.ListNode;
/**
* @program: zyfboot-javabasic
* @description: 两两交换链表中的节点(中等)
* @author: zhangyanfeng
* @create: 2024-08-22 10:07
**/
public class SwapPairsSolution {
public ListNode swapPairs(ListNode head) {
// 创建一个虚拟头节点
ListNode dummy = new ListNode(0);
dummy.next = head;
// 初始化指针
ListNode prev = dummy;
// 迭代地交换相邻节点
while (prev.next != null && prev.next.next != null) {
ListNode first = prev.next;
ListNode second = first.next;
// 调整指针以交换节点
first.next = second.next;
second.next = first;
prev.next = second;
// 移动 prev 指针到下一个要处理的节点对
prev = first;
}
// 返回新链表的头节点
return dummy.next;
}
public static void main(String[] args) {
SwapPairsSolution solution = new SwapPairsSolution();
// 测试用例 1
ListNode l1 = new ListNode(1);
l1.next = new ListNode(2);
l1.next.next = new ListNode(3);
l1.next.next.next = new ListNode(4);
ListNode result1 = solution.swapPairs(l1);
printList(result1); // 输出应该为 [2, 1, 4, 3]
// 测试用例 2
ListNode l2 = new ListNode(1);
ListNode result2 = solution.swapPairs(l2);
printList(result2); // 输出应该为 [1]
// 测试用例 3
ListNode result3 = solution.swapPairs(null);
printList(result3); // 输出应该为 []
}
// 打印链表的辅助函数
private static void printList(ListNode node) {
while (node != null) {
System.out.print(node.val + " ");
node = node.next;
}
System.out.println();
}
}
具体可参考:https://zyfcodes.blog.csdn.net/article/details/141401712