题目链接:https://leetcode.com/problems/reorder-list/
题目:
L: L0→L1→…→Ln-1→Ln,
reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→…
You must do this in-place without altering the nodes' values.
For example,
Given {1,2,3,4}
, reorder it to {1,4,2,3}
.
思路:
划分后半段链表,找到它的表头。然后将它反转,再和前半段链表交叉合并。其中划分链表、反转部分代码在Palindrome Linked List 中已有实现,
只需添加交叉合并操作就可以了。
算法:
public void reorderList(ListNode head) {
if (head == null || head.next == null) {
return;
}
int i = getListLength(head) / 2;
ListNode p = head, l2 = null;
while (i-- > 0)
p = p.next;
l2 = p.next; //此时l2指向后半段链表表头
p.next = null;
l2 = reverseList(l2);// 反转后半段链表
p = head;
while (l2 != null) {// 将两链表交叉合并,在p~t之间插入l2结点,其中t2指向l2后面结点
ListNode t = p.next;
ListNode t2 = l2.next;
p.next = l2;
l2.next = t;
l2 = t2;
p = t;
}
}
public int getListLength(ListNode head) {
int length = 0;
ListNode p = head;
while (p != null) {
length++;
p = p.next;
}
return length;
}
public ListNode reverseList(ListNode head) {
ListNode p = head, q, t;
if (p == null)
return head;
q = p.next;
while (q != null) {
t = q.next;// 保存当前要处理结点后面的一个结点
q.next = p;
p = q; // p是新链表头结点
q = t;
}
head.next = null;// 原头结点变成尾节点
head = p;
return head;
}