这道题是来自2014微软秋季校招笔试题的最后一道算法笔试题,本博客提供代码解析及代码实现!!!
第二部分测试时间为60分钟,满分50分。请务必在回答问题前仔细阅读变成题目。您可以选用C、C++、C#或者Java 其中任何一种编程语言,并且保证您的代码可以正确编译和有正确的结果。另外,请一定要注意您的代码的质量。
Given a singly linked list L: (L0 , L1 , L2...Ln-1 , Ln). Write a program to reorder it so that it becomes(L0 , Ln , L1 , Ln-1 , L2 , Ln-2...).
//思路:
L0 -> L1 -> L2 ->.....-> Ln-1 -> Ln
分解为两个单链表:
L0 -> L1 -> L2 ->....-> Ln/2
Ln/2+1 -> ....Ln
反转第二个单链表
然后合并这两个链表
代码如下:
//时间复杂度为O(N)
//空间复杂度为O(1)
//代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <stack>
#include <cassert>
#include <climits>
#include <algorithm>
#define MAXN 10010
#define RST(N)memset(N, 0, sizeof(N))
using namespace std;
typedef struct ListNode
{
int data;
struct ListNode *next;
}LNode, *pNode;
pNode Create(int n) //创建一个单链表
{
pNode p1, p2, head;
head = NULL;
p1 = p2 = (pNode)malloc(sizeof(LNode));
int flag = 1;
while(n--)
{
cin >> p1->data;
if(flag)
{
head = p1;
flag = 0;
}
else
p2->next = p1;
p2 = p1;
p1 = (pNode)malloc(sizeof(LNode));
}
p2->next = NULL;
return head;
}
pNode getMidNode(pNode head) //获取中间元素指针
{
assert(head != NULL);
pNode first = NULL;
pNode second = NULL;
first = second = head;
while(first->next != NULL && first->next->next != NULL) //这里注意
{
first = first->next->next;
second = second->next;
}
return second;
}
pNode LNReverse(pNode head) //单链表的反转
{
assert(head != NULL);
pNode Cur, Next, Nnext;
Cur = head;
Next = Nnext = NULL;
while(Cur->next != NULL)
{
Next = Cur->next;
Nnext = Next->next;
Next->next = head;
Cur->next = Nnext;
head = Next;
}
return head;
}
pNode MergeList(pNode head1, pNode head2) //合并两个单链表
{
if(head1 == NULL) return head2;
if(head2 == NULL) return head1;
pNode p1 = head1;
pNode p2 = head2;
pNode cur1 = NULL;
pNode cur2 = NULL;
while(p1!=NULL && p2!=NULL)
{
cur1 = p1->next;
cur2 = p2->next;
p1->next = p2;
p2->next = cur1;
p1 = cur1;
p2 = cur2;
}
return head1;
}
int main()
{
int n;
while(cin >> n)
{
pNode head = Create(n); //初始化
pNode head1 = head;
pNode pTemp = getMidNode(head); //获取中间元素指针
pNode head2 = pTemp->next; //截断
pTemp->next = NULL;
head2 = LNReverse(head2); //反转
head = MergeList(head1, head2); //合并
for(pNode p=head; p!=NULL; p=p->next) //结果,测试
{
cout << p->data;
if(p->next != NULL) cout << " ";
else cout << endl;
}
}
return 0;
}