题目描述:
L0 → L1 → … → Ln - 1 → Ln
请将其重新排列后变为:
L0 → Ln → L1 → Ln - 1 → L2 → Ln - 2 → …
不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
题目解答:
class Solution {
public ListNode findmidNode(ListNode head) {
// 找到中间结点
ListNode slow = head, fast = head;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
}
return slow;
}
public ListNode reverseList(ListNode head) {
// 翻转链表
ListNode p = head, q = null;
while (p != null) {
ListNode t = p.next;
p.next = q;
q = p;
p = t;
}
return q;
}
public void mergeList(ListNode l1, ListNode l2) {
// 合并链表
while (l1 != null && l2 != null) {
ListNode l1_next = l1.next, l2_next = l2.next;
l1.next = l2;
l1 = l1_next;
l2.next = l1;
l2 = l2_next;
}
}
public void reorderList(ListNode head) {
if (head == null)
return;
ListNode mid = findmidNode(head);
ListNode l1 = head, l2 = mid.next;
mid.next = null;
l2 = reverseList(l2);
mergeList(l1, l2);
}
}
题目思路:
思路来自力扣官方题解,即把这个过程分解为三道简单题
寻找链表中点 + 反转链表 + 合并链表
【力扣刷题练习】876. 链表的中间结点
【力扣刷题练习】206. 反转链表
【力扣刷题练习】21. 合并两个有序链表
首先找到整个链表的中间结点将链表一分为二,接着将后一个链表反转,最后将它们俩合并(这里的合并并不需要做排序处理,直接对应插入即可),这道题同时使用了链表中的多种常见操作,是一道较好的练习题。