智商拙计,做了有些时间才对,抱着试一试的心态先用了个递归的暴力找最后节点的方法,超时,关键是解决如何高效的取得最后一个节点,可以先把后半截链表倒转一下,然后merge两个链表,总共节点数为偶数时merge时刚刚能够一一配对,奇数时则会多出一个,补上即可。中间分割链表的时候不小心又出了好些bug,有些事情总是要被拆穿啊~
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* reverse(ListNode* head) {
if (head == NULL) {
return NULL;
}
ListNode* pre = NULL;
ListNode* cur = head;
while (cur != NULL) {
ListNode* tmp = cur->next;
cur->next = pre;
pre = cur;
cur = tmp;
}
return pre;
}
void reorderList(ListNode *head) {
if (head == NULL || head->next == NULL) {
return;
}
int num = 0;
ListNode* cur = head;
while (cur != NULL) {
num++;
cur = cur->next;
}
// seperate list, find middle node as the head of the new list
int ridx = num / 2;
ListNode* rhead = NULL;
cur = head;
for (int i=0; true; i++) {
if (i == ridx - 1) {
rhead = cur->next;
cur->next = NULL;
break;
}
cur = cur->next;
}
rhead = reverse(rhead);
// build final list
cur = head;
head = head->next;
cur->next = rhead;
cur = rhead;
rhead = rhead->next;
while (head != NULL && rhead != NULL) {
cur->next = head;
cur = head;
head = head->next;
cur->next = rhead;
cur = rhead;
rhead = rhead->next;
}
cur->next = rhead; // there must be only one node left(odd case) or NULL(even case)
}
};
还是附上naive版本吧,too young, too simple
/**
* 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 == NULL || head->next == NULL) {
return;
}
ListNode* tail = head;
ListNode* prev = NULL;
while (tail->next != NULL) {
prev = tail;
tail = tail->next;
}
prev->next = NULL;
reorderList(head->next);
tail->next = head->next;
head->next = tail;
}
};