题目:给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题。
👍交换链表基本知识:
首先我们要清晰地知道,在交换链表结点位置时,只需要控制该节点前后结点的next指向正确的位置即可。例如:我想要交换结点2和结点3的位置,我需要的步骤:
①结点2的next指向结点4;
②结点3的next指向结点2;
③使得结点1的next指向结点3;
注意的是:如果先执行步骤③容易出错,原因是当前指针(cur)指向的是结点1,如果结点1的next先指向结点3,则cur.next不再是结点2,因为要操作该结点必须找到该节点的前一个结点,所以不可以先执行步骤③。
若要先执行步骤③,则需要另外定义一个临时结点temp来存储结点2。
👍解题思路:
方法一:我们要创建一个虚拟头节点(dummyHead),有利于操作head结点;创建一个firstNode的临时结点,来保存要交换的两个结点之间的第一个结点;创建一个secondNode的临时结点,来保存要交换的两个结点之间的第二个结点;创建temp结点,来保存两个结点后面的结点。
public ListNode swapPairs(ListNode head) {
ListNode dummyHead = new ListNode(-1); //虚拟头节点
dummyHead.next=head; //把虚拟头节点指向head结点
ListNode cur =dummyHead;
ListNode temp;
ListNode firstNode;
ListNode secondNode;
while (cur.next!=null && cur.next.next!=null){
temp=cur.next.next.next;
firstNode=cur.next; //对第一个结点赋值
secondNode=cur.next.next; //对第二个节点进行赋值
//进行交换操作
cur.next=secondNode;
secondNode.next=firstNode;
firstNode.next=temp;
cur=firstNode;
}
return dummyHead.next;
}
图解如下:
方法二:使用递归方法。
使用递归方法是先交换结点3和结点4,最后再交换结点1和结点2。
public ListNode swapPairs1(ListNode head) {
if (head==null || head.next==null){
return head; //如果该结点为null则返回该节点。
}
ListNode next=head.next;
//进行递归
ListNode newNode=swapPairs(next.next); //把当前head结点的next的next结点作为head结点参数递归调用交换方法。
//进行交换
next.next=head;
head.next=newNode;
return next;
}