题目
思路
首先将链表分为前半段和后半段
例如:1 -> 2 -> 3 -> 4
被分为1 -> 2
和3 -> 4
如果链表长度为计数,需要确保链表的前半段比后半段多一个节点
怎么找到链表的上中位点?用快慢指针:
ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode slow = dummy;
ListNode fast = dummy;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
}
当循环结束时,slow就是链表的上中位点
然后把后半段链表反转,形成4 -> 3
最后从前半段链表和后半段链表的头节点开始,逐个把它们的节点连接起来形成一个新的链表
形成1 -> 3 -> 2 -> 4
代码
public void reorderList(ListNode head) {
ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode slow = dummy;
ListNode fast = dummy;
// dummy 1 2 3 4 5 6 7
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
}
ListNode list2 = reverse(slow.next);
slow.next = null;
ListNode list1 = dummy.next;
ListNode newListDummy = new ListNode(0);
ListNode newList = newListDummy;
// link
while (list1 != null) {
newList.next = list1;
list1 = list1.next;
newList = newList.next;
if (list2 != null) {
newList.next = list2;
list2 = list2.next;
newList = newList.next;
}
}
head.next = newListDummy.next.next;
}
private ListNode reverse(ListNode head) {
ListNode pre = null;
while (head != null) {
ListNode next = head.next;
head.next = pre;
pre = head;
head = next;
}
return pre;
}