第一种思路:(时间:144ms 内存:12MB)
1.指针找到中点
2.拆成两个链表 ,拆成前后两条链line1,line2。逆置line2.
3.遍历两个链表,后面的塞到前面的“缝隙里”。
节点为偶数时:size(line1)=size(line2)
节点为奇数时:size(line1)=size(line2)+1;
省去了每次找链尾的时间。当链表很长时效果明显。然而内存并没有明显改善。
第二种思路:双端队列
优点:简洁
/**
* 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* p = head, *q;
int count = 0;
while (p != NULL)
{
p = p->next;
count++;
}
p = head;
//找中间位置
for (int i = 1; i < (count +1) / 2; i++)//len(line1)>=len(line2)
p = p->next;
//拆成两条链,添加头结点
ListNode* line1 = new ListNode(-1);
line1->next = head;
ListNode* line2 = new ListNode(-1);
line2->next = p->next;
p->next = NULL;
//逆置第二条链
reverse(line2);
p = line1->next;
q = line2->next;
while (p&&q)
{
ListNode* tmp = q;
q = q->next;
tmp->next = p->next;
p->next = tmp;
p = p->next->next;
}
head = line1->next;
return;
}
void reverse(ListNode *head)
{
ListNode*p = head->next;
head->next = NULL;
while (p)
{
ListNode* q = p;//这里千万要记录p,否则p->next变成了NULL
p = p->next;
q->next = head->next;
head->next =q;
}
}
};
//第二种思路
class Solution {
public void reorderList(ListNode head) {
LinkedList<ListNode> queue = new LinkedList<>();
ListNode cur = head;
while (cur != null) {
queue.addLast(cur);
cur = cur.next;
}
while (!queue.isEmpty()) {
if (cur == null) {
cur = queue.pollFirst();
} else {
cur.next = queue.pollFirst();
cur = cur.next;
}
cur.next = queue.pollLast();
cur = cur.next;
}
if (cur != null) {
cur.next = null;
}
}
}