五、两两交换链表中的节点
题目:
给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。
示例1:
输入:head = [1,2,3,4] 输出:[2,1,4,3] |
示例2:
输入:head = [] 输出:[] |
示例3:
输入:head = [1] 输出:[1] |
提示:
- 链表中节点的数目在范围 [0, 100] 内
- 0 <= Node.val <= 100
解题思路分析:
虚拟头节点:
要交换1、2节点,必须要知道1节点的前一个节点才行;
例如下图,要交换1、2节点,则需要先知道dummyHead节点的位置:
当交换1和2时,current指向dummyHead:
当交换3和4时,current指向节点1:
当current.next=null(奇数个节点)时,结束循环。
代码讲解:
//定义虚拟头节点,虚拟头节点指向head
ListNode dummyhead = new ListNode(-1,head);
//定义临时指针current,指向要交换的两个节点的前一个节点
LsitNode current = dummyhead;
//遍历链表,交换节点
//遍历的终止条件:如果是奇数个节点,current.next = null;偶数个节点,则current.next.next = null
while(current.next != null && current.next.next != null) {
//定义临时节点temp1,保存一下两节点中的第一个节点(否则current.next一变,就找不到原先的next节点了)
ListNode temp1 = current.next;
//定义临时节点temp2,保存一下两节点后面的节点,否则也会丢
ListNode temp2 = current.next.next.next;
//第一步:current指向第二个节点
current.next = current.next.next;
//第二步:第二个节点指向第一个节点
current.next.next = temp1;
//第三步:第一个节点指向第三个节点
temp1.next = temp1;
//第四步,移动指针,准备下一次交换
current = current.next.next;
}
return dummyHead.next;
注意:
这里的易错点在于while循环的终止条件,分为奇数个节点和偶数个节点两种情况
题解:
自己的思路:
用了双指针+临时指针来做这道题,思路类似于上一小节的反转链表:
代码随想录:
用了一个临时指针current来解决交换问题:(还包含两个用来记录位置的临时指针)