题目描述
给定一个链表,两两交换其中相邻的节点,并返回交换后的头节点。这里不能只改节点里的值,得真的把节点位置换掉。
思路
这题最省心的写法,是先补一个虚拟头节点,再按两个节点一组去处理。这样做的好处很直接:头节点也能和普通节点一样处理,不用单独分支。
每一轮都盯着 cur.next 和 cur.next.next。前者是这一组里的第一个节点 first,后者是第二个节点 second。交换的时候不需要真的'搬家'两次,链表指针改四处就够了:先让 cur.next 跳过 first,指向 second;再让 second.next 指向 first;最后把 first.next 接回后面的剩余链表。
我更喜欢把 cur 留在已经处理好的那一段尾部。这样下一轮直接从新位置继续,不容易把指针绕乱。这个写法看起来步骤多,实际比递归稳定,也更适合顺手写一遍过。
执行流程
- 创建虚拟头节点
dummy,让它指向head。 - 定义指针
cur指向dummy。 - 只要
cur.next和cur.next.next都存在,就继续交换。 - 记录当前这一组的第一个节点
first = cur.next。 - 让
cur.next指向second,也就是cur.next.next。 - 再把
second.next指向first。 first.next接回剩余链表。cur后移到first,准备处理下一组。
代码实现
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Solution {
static class ListNode {
int val;
ListNode next;
ListNode(int val) { this.val = val; }
ListNode(int val, ListNode next) { this.val = val; this.next = next; }
}
public static void main IOException {
( (System.in));
String[] s = in.readLine().split();
(Integer.parseInt(s[]));
head;
( ; i < s.length; i++) {
(Integer.parseInt(s[i]));
cur.next = node;
cur = cur.next;
}
swapPairs(head);
cur = newHead;
(cur != ) {
System.out.print(cur.val + );
cur = cur.next;
}
}
ListNode {
(head == || head.next == ) {
head;
}
(-, head);
dummy;
(cur.next != && cur.next.next != ) {
cur.next;
cur.next = cur.next.next;
cur.next.next;
cur.next.next = first;
first.next = second;
cur = cur.next.next;
}
dummy.next;
}
}

