开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 1 天,点击查看活动详情
一、题目
给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。
二、思路
这种题目可以通过画图来理解。
以上是一个链表图,这里使用dummy虚拟节点将1234串联起来。
-
虚拟节点:因为头节点前方无节点,经常需要特殊化处理head节点,所以引入虚拟节点。
通过上面的图,所以我们的思路可以分为两步来解决这个问题。
1.局部调整(交换)
我们模拟了一下1、2两个节点单次交换的逻辑,一共分为4个步骤
-
记录pre和3节点位置,防止断链 -
将2节点 指向 1节点 -
将 1节点 指向 3节点 -
将 pre节点(指交换位置的1节点之前的节点,本次是dummy)指向2节点
最终,四个部分完成了 1、2两个节点的交换。
使用1、2两个节点相邻的两个节点pre节点和3节点记录了一下位置,保证链路不会断链。
2.循环迭代 每次循环前需要确保,本次交换的两个节点存在。
while (one != null && one.next != null)
三、代码
class Solution {
public ListNode swapPairs(ListNode head) {
//虚拟节点
ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode one = head;
//1.记录pre的位置
ListNode pre = dummy;
while (one != null && one.next != null){
ListNode two = one.next;
//1.记录next的位置
ListNode three = two.next;
//2.将2节点 指向 1节点
two.next = one;
//3.将 1节点 指向 3节点
one.next = three;
//4.将 pre节点指向2节点
pre.next = two;
pre = one;
one = three;
}
return dummy.next;
}
}
四、总结
画图可以让思路变得更清晰,建议做题前可以先把图画出来
开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 1 天,点击查看活动详情