题目简介:
给定一个单链表 L:L0→L1→…→L n-1→Ln ,
将其重新排列后变为: L0→L n→L1→L n-1→L2→L n-2→…
你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
示例 1:
1
| 给定链表 1->2->3->4, 重新排列为 1->4->2->3.
|
示例 2:
1
| 给定链表 1->2->3->4->5, 重新排列为 1->5->2->4->3.
|
思路:
分成三步:
- 找到链表中点的前驱结点(快慢指针法)
- 将前后两部分链表断开,再将后一半链表逆转
- 将后一半逆转的链表并入前一部分链表
tip:
- 注意要将两部分链表先断开,所以找的是中点的前驱结点。
代码如下:
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 77 78
|
class Solution { public:
ListNode* middle_node(ListNode* head){
ListNode* quick = head; ListNode* slow = head;
while(quick -> next && quick -> next -> next){
slow = slow -> next; quick = quick -> next -> next; }
return slow; }
ListNode* reverse(ListNode* head){
ListNode* cur = head; ListNode* pre = NULL;
while(cur){
ListNode* next_node = cur -> next;
cur -> next = pre; pre = cur;
cur = next_node; }
return pre; }
void merge(ListNode* l1, ListNode* l2){
ListNode* l1_next; ListNode* l2_next;
while(l1 && l2){
l1_next = l1 -> next; l2_next = l2 -> next;
l1 -> next = l2; l1 = l1_next;
l2 -> next = l1; l2 = l2_next; } }
void reorderList(ListNode* head) {
if(!head) return; ListNode* middle = middle_node(head);
ListNode* l2 = middle -> next; middle -> next = NULL;
l2 = reverse(l2);
merge(head, l2); } };
|