这个题折磨了我不止一个小时……
首先利用快慢指针,找到链表的中间节点,将前半部分保序,而后半部分逆转。之后,再将后半部分隔空插到前半部分中。
难点在于链表的各种处理……
/**
* 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 *f, *s, *t = NULL;
f = s = head;
while (f->next != NULL) {
if (f->next->next == NULL)
f = f->next;
else
f = f->next->next;
if (f->next == NULL)
t = s;
s = s->next;
if (f->next == NULL)
t->next = NULL;
}
ListNode *last = NULL;
while (s != NULL) {
ListNode *tmp = s->next;
s->next = last;
last = s;
s = tmp;
}
ListNode *p, *q;
p = head;
q = last;
int i = 0;
while (p->next != NULL && q->next != NULL) {
if (i % 2 == 0) {
ListNode *t_q = q->next;
q->next = p->next;
p->next = q;
q = t_q;
p = p->next->next;
}
++i;
}
p->next = q;
}
};
其实我最早是写了一个递归的,坏处就是时间复杂度太高,但是写起来明显简单不少啊有木有!所以我觉得如果数据很少的时候,这个 O(n^2) 的代码也是可以接受的。
class Solution {
public:
void reorderList(ListNode *head) {
if (head == NULL)
return;
ListNode *l, *r;
l = head;
r = head;
while (r->next != NULL)
r = r->next;
helper(head, r);
}
ListNode *helper(ListNode *l, ListNode *r) {
if (l == r) {
l->next = NULL;
return l;
}
if (l->next == r) {
r->next = NULL;
return l;
}
ListNode *t = l;
while (t->next != r)
t = t->next;
ListNode *l_next = l->next;
l->next = r;
r->next = helper(l_next, t);
return l;
}
};
http://oj.leetcode.com/problems/reorder-list/