给定一个链表,对于每两个相邻的结点,交换其位置。
如 1->2->3->4->null,返回2->1->3->4->null
只能对结点进行操作,不能修改结点的值,只能操作结点(整个)或结点对应的指针。
分析:因为头结点没有前驱,不便于遍历,需要添加一个虚拟头结点,始终让该结点指向实际链表的头结点。
注意:想不清楚就画图,要明白每一个变量的含义和作用。其实next指针可以不用的,自己想想如何处理。
共用代码:
public class ListNode { public int val; public ListNode next; public ListNode(int x) { this.val = x; this.next = null; } public static ListNode createList(int[] nums) { if(null == nums || 0 == nums.length) return null; ListNode head = new ListNode(nums[0]); ListNode needle = head; for(int i = 1; i < nums.length;++i) { ListNode node = new ListNode(nums[i]); needle.next = node; needle = needle.next; needle.next = null; } return head; } }// 24 使用虚拟头结点 public ListNode swapPairs(ListNode head) { ListNode dummyHead = new ListNode(-1); dummyHead.next = head; ListNode pre = dummyHead; // 链表必须至少两个结点才可以交换,不好理解画图会更直观 while (pre.next != null && pre.next.next != null) { // 指向待交换的第一个结点 ListNode node1 = pre.next; // 指向待交换的第二个结点 ListNode node2 = node1.next; // 记录待交换的第二个结点的下一个结点,避免剩余结点的丢失 ListNode next = node2.next; // 真正的交换,交换的是指针的指向 node2.next = node1; node1.next = next; // 移动指针,为下次交换做准备,第一个node2是新的头结点 pre.next = node2; // 指针向前移动2个位置(注意while中用的是pre.next和pre.next.next) pre = node1; } return dummyHead.next; }