Reorder List

143. Reorder List

题目链接:https://leetcode.com/problems/reorder-list/#/description

题目大意:给定一个单向链表 LL0→L1→…→Ln-1→Ln,要求返回重新组织的链表:L0→LnL1→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 };

评测系统上运行结果:

 

posted @ 2017-05-27 14:53  小谷子的博客园  阅读(127)  评论(0编辑  收藏  举报