143. Reorder List
题目链接:https://leetcode.com/problems/reorder-list/#/description
题目大意:给定一个单向链表 L: L0→L1→…→Ln-1→Ln,要求返回重新组织的链表:L0→Ln→L1→Ln-1→L2→Ln-2→…。要求不能申请额外的空间,并且不能修改节点的值。例如给定{1,2,3,4},重排后为{1,4,2,3}。
思路:使用快慢指针把初始链表拆分成两个长度相等的链表(如果链表节点个数为奇数,则第一个链表的节点个数多一),然后将第二个链表翻转,最后将两个链表合并成一个链表。
算法复杂度:时间复杂度为O(n),空间复杂度为O(1)
代码:
1 /** 2 * Definition for singly-linked list. 3 * struct ListNode { 4 * int val; 5 * ListNode *next; 6 * ListNode(int x) : val(x), next(NULL) {} 7 * }; 8 */ 9 class Solution { 10 public: 11 void reorderList(ListNode* head) { 12 auto mid = splitList(head); 13 if (!mid) 14 return; 15 mid = reverseList(mid); 16 mergeLists(head, mid); 17 } 18 private: 19 ListNode *splitList(ListNode* head) { 20 if (!head) 21 return head; 22 ListNode *slow = head, *fast = head; 23 while (fast && fast->next && fast->next->next) { 24 slow = slow->next; 25 fast = fast->next->next; 26 } 27 auto mid = slow->next; 28 slow->next = nullptr; 29 return mid; 30 } 31 ListNode *reverseList(ListNode* head) { 32 if (!head) 33 return head; 34 ListNode *pre = nullptr; 35 while (head) { 36 auto next = head->next; 37 head->next = pre; 38 pre = head; 39 head = next; 40 } 41 return pre; 42 } 43 void mergeLists(ListNode *first, ListNode *second) { 44 ListNode *pf = first->next, *ps = second, *pm = first; 45 while (pf && ps) { 46 pm->next = ps; 47 ps = ps->next; 48 pm->next->next = pf; 49 pf = pf->next; 50 pm = pm->next->next; 51 } 52 pm->next = pf ? pf : ps; 53 } 54 };
评测系统上运行结果: