143. 重排链表
题目描述
给定一个单链表 L 的头节点 head ,单链表 L 表示为:
1
| L0 → L1 → … → Ln - 1 → Ln
|
请将其重新排列后变为:
1
| L0 → Ln → L1 → Ln - 1 → L2 → Ln - 2 → …
|
不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
输入输出
1 2 3 4 5
| 输入:head = [1,2,3,4] 输出:[1,4,2,3]
输入:head = [1,2,3,4,5] 输出:[1,5,2,4,3]
|
基本思路
方法一:
- 链表不支持下标访问,所以无法随机访问链表中任意位置的元素。因此比较容易想到的一个方法是,利用线性表存储该链表,然后利用线性表可以下标访问的特点,直接按顺序访问指定元素,重建该链表即可。
- 性能:
- 时间复杂度:$O(N)$,其中 N 是链表中的节点数。
- 空间复杂度:$O(N)$,其中 N 是链表中的节点数。主要为线性表的开销。
方法二:目标链表即为将原链表的左半端和反转后的右半端合并后的结果
- 找到原链表的中点(参考「876. 链表的中间结点」)
- 将原链表的右半端反转(参考「剑指 Offer 24. 反转链表」)
- 将原链表的两端合并
- 性能:
- 时间复杂度:$O(N)$,其中 N 是链表中的节点数。
- 空间复杂度:$O(1)$
java实现
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 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
| class Solution { public void reorderList(ListNode head) { if(head == null) return; List<ListNode> list = new ArrayList<ListNode>(); ListNode node = head; while(node != null){ list.add(node); node = node.next; } int i = 0, j = list.size() - 1; while(i < j){ list.get(i).next = list.get(j); i++; if(i == j) break; list.get(j).next = list.get(i); j--; } list.get(i).next = null; } }
class Solution { public void reorderList(ListNode head) { if(head == null) return; ListNode midnode = middleNode(head); ListNode p1 = head; ListNode reverse_node = midnode.next;
midnode.next = null; ListNode p2 = reverse(reverse_node); mergeTwoLists(p1, p2); }
public ListNode reverse(ListNode head){ ListNode cur = head, pre = null; while(cur != null){ ListNode tmp = cur.next; cur.next = pre; pre = cur; cur = tmp; } return pre; }
public ListNode middleNode(ListNode head){ int cnt = 0; ListNode node = head; while(node != null){ cnt++; node = node.next; } int findnode = cnt / 2; node = head; for(int i = 0; i < findnode; i++){ node = node.next; } return node; }
public void mergeTwoLists(ListNode p1, ListNode p2){ ListNode p1_tmp, p2_tmp; while(p1 != null && p2 != null){ p1_tmp = p1.next; p2_tmp = p2.next; p1.next = p2; p1 = p1_tmp; p2.next = p1; p2 = p2_tmp; } } }
|