LeetCode 143. Reorder List
题目描述
给定一个单链表 $L:L_0→L_1→…→Ln-1→L_n$ ,
将其重新排列后变为: $L_0→L_n→L_1→Ln-1→L_2→Ln-2→…$
你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
示例 1:
给定链表 1->2->3->4
, 重新排列为 1->4->2->3
.
示例 2:
给定链表 1->2->3->4->5
, 重新排列为 1->5->2->4->3
.
解题思路
给定链表 1->2->3->4->5
, 重新排列为 1->5->2->4->3
.
通过观察,可以将重排链表分解为以下三个步骤:
- 首先重新排列后,链表的中心节点会变为最后一个节点。所以需要先找到链表的中心节点:876. 链表的中间结点
- 可以按照中心节点将原始链表划分为左右两个链表。
- 按照中心节点将原始链表划分为左右两个链表,左链表:
1->2->3
右链表:4->5
。
- 将右链表反转,就正好是重排链表交换的顺序,右链表反转:
5->4
。反转链表:206. 反转链表
- 合并两个链表,将右链表插入到左链表,即可重新排列成:
1->5->2->4->3
.
代码
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 79 80 81 82
|
struct ListNode* middleNode(struct ListNode* head){ struct ListNode* fast = head, *slow = head; while(fast != NULL && fast->next != NULL){ fast = fast->next->next; slow = slow->next; } return slow; }
struct ListNode* reverseList(struct ListNode* head){ if(!head || !head->next) return head; struct ListNode *L = malloc(sizeof(struct ListNode)), *p; L->next = NULL; while(head != NULL) { p = head->next; head->next = L->next; L->next = head; head = p; } return L->next; }
void mergeList(struct ListNode* left, struct ListNode* right){ struct ListNode *leftTemp, *rightTemp;
while(right != NULL){ leftTemp = left->next; rightTemp = right->next;
left->next = right; right->next = leftTemp;
left = leftTemp; right = rightTemp; } }
void reorderList(struct ListNode* head){ if(!head || !head->next) return head;
struct ListNode *middle = middleNode(head); struct ListNode *left = head, *right = middle->next; middle->next = NULL;
right = reverseList(right);
mergeList(left, right); }
|