题目要求:
Given a singly linked list L: L0→L1→…→Ln-1→Ln,
reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→…
You must do this in-place without altering the nodes' values.
For example,
Given {1,2,3,4}
, reorder it to {1,4,2,3}
.
刚看到题目,第一个冒出来的想法如下:
对应程序如下:
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 if (!head || !head->next || !head->next->next) 13 return; 14 15 ListNode *start = head, *end = nullptr; 16 bool flag = true; 17 while (start->next && start->next->next) 18 { 19 if (flag) 20 head = start; 21 flag = false; 22 23 end = start; 24 auto preEnd = end; 25 while (end->next) 26 { 27 preEnd = end; 28 end = end->next; 29 } 30 31 preEnd->next = nullptr; 32 auto next = start->next; 33 start->next = end; 34 end->next = next; 35 36 start = next; 37 } 38 } 39 };
但超时了!!!
后来参考了网上别人的通用解法:
1)用快慢指针找到中间节点,将链表分成两部分。
2)对后面一半的链表逆序,这个也是常见的问题了(链表反转)。
3)合并两个链表。
具体程序如下(72ms):
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 if (!head || !head->next || !head->next->next) 13 return; 14 15 ListNode *slow = head, *fast = head; 16 while(fast->next && fast->next->next) 17 { 18 slow = slow->next; 19 fast = fast->next->next; 20 } 21 22 ListNode *mid = slow->next; 23 ListNode *prev = nullptr; 24 while(mid) 25 { 26 ListNode *next = mid->next; 27 mid->next = prev; 28 prev = mid; 29 mid = next; 30 } 31 slow->next = nullptr; 32 33 ListNode *start = head; 34 bool flag = true; 35 while (start && prev) 36 { 37 ListNode *next = start->next; 38 start->next = prev; 39 prev = prev->next; 40 start->next->next = next; 41 42 if (flag) 43 head = start; 44 flag = false; 45 46 start = next; 47 } 48 49 } 50 };