题目描述:
给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。
你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
示例:
给定 1->2->3->4, 你应该返回 2->1->4->3.
思想:
新建虚拟头结点dummy,使得dummy.next始终指向第一个结点,然后定义临时结点,三行代码(固定顺序)交换即可,建议看着代码,画图,便于理解。注意一下循环的条件,是后续存在两个结点时才循环。
PS:链表结点交换固定套路,注意cur指针始终指向后续交换的两个结点的前一个。
解释:为什么是这个固定顺序?
第一步:
假如先执行(2),即temp.next = cur.next,那么结点2和结点3之间连线断开,结点3就找不到了
假如先执行(3),即cur.next = temp,那么结点dummy和结点1之间连线断开,结点1就找不到了
所以必须先执行(1),即cur.next.next = temp.next
第二步:
假如先执行(3),即cur.next = temp,那么结点dummy和结点1之间连线断开,结点1就找不到了
所以必须执行(2),即temp.next = cur.next。
class ListNode{
int val;
ListNode next;
public ListNode(int x) {
val = x;
}
}
public class test1 {
public static ListNode swapPairs(ListNode head) {
//处理特殊情况
if(head.next == null) return null;
//新建虚拟头结点
ListNode dummy = new ListNode(-1);
ListNode cur = dummy;
//dummy.next用于始终指向第一个结点
//cur是滑动指针
dummy.next = head;
//当后续存在两个值时,才进行交换
while(cur.next != null && cur.next.next != null) {
//新建临时结点,交换
ListNode temp = cur.next.next;
cur.next.next = temp.next;
temp.next = cur.next;
cur.next = temp;
//更新cur后移两位即可
cur = temp.next;
}
return dummy.next;
}
//初始化链表
public static void add(ListNode node, int[] data) {
ListNode temp = node;
if(data.length == 0) return;
for(int i = 0; i < data.length; i++) {
temp.next = new ListNode(data[i]);
temp = temp.next;
}
}
//打印链表
public static void LinkedPrint(ListNode node) {
if(node == null) return;
while(node != null) {
System.out.println(node.val + " ");
node = node.next;
}
}
public static void main(String[] args) {
ListNode l1 = new ListNode(-1);
int[] nums1 = {1, 2, 3, 4};
add(l1, nums1);
ListNode result = swapPairs(l1.next);
LinkedPrint(result);
}
}