题目
解题
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode swapPairs(ListNode head) {
ListNode dummy = new ListNode();
dummy.next = head;
ListNode current = dummy;
while(current.next != null && current.next.next != null){
ListNode temp1 = current.next;
ListNode temp2 = current.next.next.next;
current.next = current.next.next;
current.next.next = temp1;
temp1.next = temp2;
current = temp1;
}
return dummy.next;
}
}
思路
这道题还是使用一个dummy
节点来指向头节点,这样的目的是为了方便操作头节点,使得头节点和后续节点的操作步骤相同
这道题其实思路非常简单,就是交换两个元素的位置,但是具体是需要修改三个指针的方向的。
画图如下:
从图中我们可以看到,虽然交换2、3
的位置,但是1、2、3
的指针指向都需要变化。所以这道题当我们要交换两个元素的位置时,我们需要将指针指向两个元素的前一个元素,然后改变三个元素的指针。
其次我们还需要注意这个链表的个数,奇数偶数的结束条件是不相同的。
- 偶数:两两交换最后会指向最后一个元素,那么这个元素的
node.next == null
- 奇数:两两交换后会在倒数第二个元素,因为它需要在交换元素的前一个元素,最后就会指向倒数第二个元素,那么这个元素的
node.next.next == null
这两个刚好是我们循环结束的条件,因为在这两种条件下,是没有可交换的元素了。
注意这两个条件的位置不能交换,因为如果是偶数的话它的下一个就为null
了,那么先走node.next.next
就会报空指针错误。
最后就是交换时候的细节:(按照上面图)
- 我们需要临时保存 2 节点,因为当我们 1 节点指向 3 节点之后,不保存的话就会造成 2 节点的丢失。
- 我们需要临时保存 3 节点的下一个节点,因为当我们把 3 节点指向 2 节点之后,就会把 3 节点的下一个节点丢失。