题目描述:
给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。
你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
示例: 输入:head = [1,2,3,4] 输出:[2,1,4,3]
思路分析:
用递归或是迭代方法来解决
递归法分析:
可以通过递归的方式实现两两交换链表中的节点。
递归的终止条件是链表中没有节点,或者链表中只有一个节点,此时无法进行交换。
如果链表中至少有两个节点,则在两两交换链表中的节点之后,原始链表的头节点变成新的链表的第二个节点,原始链表的第二个节点变成新的链表的头节点。链表中的其余节点的两两交换可以递归地实现。在对链表中的其余节点递归地两两交换之后,更新节点之间的指针关系,即可完成整个链表的两两交换。
递归的主要写法:只要抓住f(x)一个功能函数去写,后面直接套上去就行,具体详见下面的代码注释:
public ListNode swapPairs(ListNode head) {
//边界条件判断
if (head == null || head.next == null)
return head;
//从第3个链表往后进行交换(实现递归一个f(x))
ListNode third = swapPairs(head.next.next);
//从第3个链表往后都交换完了,我们只需要交换前两个链表即可,
//这里我们把链表分为3组,分别是第1个节点,第2个节点,后面
//的所有节点,也就是1→2→3,我们要把它变为2→1→3
ListNode second = head.next;//second表示新的链表的头结点,原链表的第二个结点
head.next = third;
second.next = head;
return second;
}
迭代实现:
可以通过迭代的方式实现两两交换链表中的节点。
创建哑结点 dummyHead,令 dummyHead.next = head。令 temp 表示当前到达的节点,初始时 temp = dummyHead。每次需要交换 temp 后面的两个节点。
如果 temp 的后面没有节点或者只有一个节点,则没有更多的节点需要交换,因此结束交换。否则,获得 temp 后面的两个节点 node1 和 node2,通过更新节点的指针关系实现两两交换节点。
class Solution {
public ListNode swapPairs(ListNode head) {
ListNode dummyHead = new ListNode(0);
dummyHead.next = head;
ListNode temp = dummyHead;
while (temp.next != null && temp.next.next != null) {
ListNode node1 = temp.next;
ListNode node2 = temp.next.next;
temp.next = node2;
node1.next = node2.next;
node2.next = node1;
temp = node1;
}
return dummyHead.next;
}
}