给定一个单链表 L
的头节点 head
,单链表 L
表示为:
L0 → L1 → … → Ln-1 → Ln
请将其重新排列后变为:
1
| L0 → Ln → L1 → Ln-1 → L2 → Ln-2 → …
|
不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
示例 1:

1 2
| 输入: head = [1,2,3,4] 输出: [1,4,2,3]
|
示例 2:

1 2
| 输入: head = [1,2,3,4,5] 输出: [1,5,2,4,3]
|
提示:
- 链表的长度范围为
[1, 5 * 104]
1 <= node.val <= 1000
先找到中间节点
然后将后半部分反转
然后将后半部分依次插入到前半部分
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
|
class Solution { public ListNode reorderList(ListNode head) { if(head == null || head.next == null || head.next.next == null) return head; ListNode pre = middleNode(head); pre.next = reverseList(pre.next); ListNode head2 = pre.next; pre.next = null; ListNode p1 = head; ListNode p2 = head2; while(p2 != null){ ListNode q = p2.next; p2.next = p1.next; p1.next = p2; p1 = p1.next.next; p2 = q; } return head; }
public ListNode middleNode(ListNode head) { ListNode slow = head; ListNode fast = head.next; while(fast != null && fast.next != null){ slow = slow.next; fast = fast.next.next;
} return slow; } public ListNode reverseList(ListNode head){ if(head == null || head.next == null) return head; ListNode pre = null; ListNode p = head; while(p != null){ ListNode q = p.next; p.next = pre; pre = p; p = q; } return pre; } }
|
时间复杂度:O(n),其中 n 是链表的长度。需要使用快慢指针遍历链表,遍历链表的后一半并反转,以及反转后合并链表,每次遍历的时间复杂度都是 O(n)
空间复杂度:O(1)