描述
将给定的单链表\ L L: L_0→L_1→…→L_{n-1}→L_ nL0→L1→…→Ln−1→Ln
重新排序为:L_0→L_n →L_1→L_{n-1}→L_2→L_{n-2}→…L0→Ln→L1→Ln−1→L2→Ln−2→…
要求使用原地算法,不能只改变节点内部的值,需要对实际的节点进行交换。
数据范围:链表长度 0 \le n \le 200000≤n≤20000 ,链表中每个节点的值满足 0 \le val \le 10000≤val≤1000
要求:空间复杂度 O(n)O(n) 并在链表上进行操作而不新建链表,时间复杂度 O(n)O(n)
进阶:空间复杂度 O(1)O(1) , 时间复杂度 O(n)O(n)
示例1
输入:
{1,2,3,4}
复制返回值:
{1,4,2,3}
复制说明:
给定head链表1->2->3->4, 重新排列为 1->4->2->3,会取head链表里面的值打印输出 1
解题思路:
- 边界处理
- 找到中间节点
- 翻转后半段链表
- 归并链表
复制代码
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 | /** * Definition for singly-linked list. * class ListNode { * int val; * ListNode next; * ListNode(int x) { * val = x; * next = null; * } * } */ public class Solution { public void reorderList(ListNode head) { if (head == null || head.next == null ) return ; ListNode mid = getMid(head); ListNode midNext = mid.next; mid.next = null ; ListNode prev = null ; ListNode cur = midNext; while (cur != null ){ ListNode next = cur.next; cur.next = prev; prev = cur; cur = next; } ListNode node = head; while (node != null && prev != null ){ ListNode n1 = node.next; ListNode n2 = prev.next; node.next = prev; prev.next = n1; node = n1; prev = n2; } } public ListNode getMid(ListNode head){ ListNode slow = head; ListNode fast = head; while (fast.next != null && fast.next.next != null ){ slow = slow.next; fast = fast.next.next; } return slow; } } |