Leetcode Reorder List
实现链表如下所示:
Given a singly linked list L: L0→L1→…→Ln-1→Ln,
reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→…
一开始想到一个n方的,就是每次找最后一个回调到相应位置,然后倒数第二个的next置为NULL,依次类推。果然超时。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: void reorderList(ListNode *head) { if (!head || !head->next) return ; ListNode *cur, *last, *next_cur, *pre_last; last = head -> next; pre_last = head; while(last -> next) { pre_last = last; last = last -> next; } cur = head; next_cur = head -> next; while(cur -> next || cur -> next != last) { cur -> next = last; pre_last -> next = NULL; cur = next_cur; next_cur = cur -> next; last = cur -> next; pre_last = cur; while(last && last -> next) { pre_last = last; last = last -> next; } } return ; } };
也可以用map<int, ListNode*>来做吧应该,但用了其他空间了。下面是比较直接的没有用多余空间的解法。
分成两半,后面一半反转,然后合并前后两半。
需要注意的是,前面一半的最后一个记得赋值NULL,还有如果是奇数,那么前面一半应该多一个。自己随便举个1234和12345的例子画一下就知道怎么合并怎么分了。
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: void reorderList(ListNode *head) { if (!head || !head -> next) return ; ListNode *slow = head, *quick = head -> next; while(quick && quick -> next) // 分成两部分 { slow = slow -> next; quick = quick -> next; if (!quick) break; quick = quick -> next; } quick = slow -> next; ListNode *last = quick -> next; while(last) // 反转后半部 { quick -> next = last -> next; last -> next = slow -> next; slow -> next = last; last = quick -> next; } quick = slow -> next; slow -> next = NULL; ListNode *next_cur = head -> next, *next_quick, *cur = head; while(cur && quick) // 合并两部分 { cur -> next = quick; next_quick = quick -> next; quick -> next = next_cur; quick = next_quick; cur = next_cur; if (cur) next_cur = cur -> next; } } };