题目:原单链表: {L(0), L(1), L(2)..., L(n-2), L(n-1), L(n)}, 重新排序为:{L(0), L(n), L(1), L(n-1), L(2), L(n-2), ..., L(m)}
输入:n( n: [0, 20000])个数字:{L(0), L(1), L(2)..., L(n-2), L(n-1), L(n)}( L(n): [0, 1000] ), 输入顺序即为链表元素顺序。
输出:重排后的链表:{L(0), L(n), L(1), L(n-1), L(2), L(n-2), ..., L(m)}
限制:空间复杂度 O(1), 时间复杂度 O(n)
解题语言:C语言
解题思路:题目可看成是 对后半部分的结点逆序,逐个插入前半部分的结点中间,则问题拆解成两个问题:1)找链表的中结点位置;2)对后半部分结点逆序重排。
问题1)可利用快慢指针实现;问题2)可利用栈的特性:先入后出;
解题后的心得:
逆序问题可首先考虑栈,空间复杂度和时间复杂度均为最佳。
代码:
1. 变量定义 和 main函数
#include#include struct ListNode { int val; struct ListNode *next; }; int main(int argc, char *argv[]) { struct ListNode *pList = NULL; pList = createList(); reorderList(pList); printList(pList); return 0; }
2. 链表创建和打印输出:
struct ListNode *createList()
{
struct ListNode *pNew = NULL;
struct ListNode *pHead = NULL;
struct ListNode *pEnd = NULL;
unsigned int inputNumCount = 0;
unsigned int inputNumber = 0;
unsigned int count = 0;
printf("please input number count: ");
scanf("%u", &inputNumCount);
if (0 == inputNumCount)
{
return NULL;
}
pHead = NULL;
pEnd = NULL;
count = 0;
while (inputNumCount--)
{
printf("%u: ", count+1);
scanf("%u", &inputNumber);
pNew = (struct ListNode *)malloc(sizeof(struct ListNode));
if (NULL == pNew)
{
printf("malloc node error! inputNumCount: %un", inputNumCount);
return pNew;
}
pNew->val = inputNumber;
pNew->next = NULL;
count++;
if (1 == count)
{
pHead = pNew;
pEnd = pNew;
}
else
{
pEnd->next = pNew;
pEnd = pNew;
}
}
return pHead;
}
void printList(struct ListNode *head)
{
struct ListNode *plistNode = NULL;
if (NULL == head)
{
printf("list is NULLn");
return ;
}
plistNode = head;
while (NULL != plistNode)
{
printf("%d ", plistNode->val);
plistNode = plistNode->next;
}
printf("n");
return ;
}
3. 重排列表接口:(编码习惯:栈空间最后要销毁,避免内存泄漏)
void reorderList(struct ListNode *head)
{
struct ListNode *pFirstHalfList = NULL;
struct ListNode *pSecondHalfList = NULL;
struct ListNode *pTmpListNode = NULL;
struct ListNode *pFastNode = NULL;
struct ListNode *pSlowNode = NULL;
struct ListNode *pStackTop = NULL;
struct ListNode *pStackBottom = NULL;
struct ListNode *pTmpStackNode = NULL;
if (NULL == head)
{
//printf("list is not exit!n");
return ;
}
if (NULL == head->next ||
NULL == head->next->next)
{
//printf("list not need sortn");
return ;
}
pSlowNode = head;
pFastNode = head->next;
while(NULL != pFastNode->next &&
NULL != pFastNode->next->next)
{
pSlowNode = pSlowNode->next;
pFastNode = pFastNode->next->next;
}
pFirstHalfList = head;
pSecondHalfList = pSlowNode->next;
pSlowNode->next = NULL;
pStackBottom = (struct ListNode *)malloc(sizeof(struct ListNode));
if (NULL == pStackBottom)
{
printf("creat stack failed!n");
return ;
}
memset(pStackBottom, 0, sizeof(struct ListNode));
pStackTop = pStackBottom;
while(NULL != pSecondHalfList)
{
pTmpListNode = pSecondHalfList->next;
pSecondHalfList->next = pStackTop;
pStackTop = pSecondHalfList;
pSecondHalfList = pTmpListNode;
}
while (pStackTop != pStackBottom &&
NULL != pFirstHalfList)
{
pTmpListNode = pFirstHalfList;
pTmpStackNode = pStackTop;
pFirstHalfList = pFirstHalfList->next;
pStackTop = pStackTop->next;
pTmpStackNode->next = pTmpListNode->next;
pTmpListNode->next = pTmpStackNode;
}
if (pStackTop != pStackBottom)
{
pTmpStackNode->next = pStackTop;
pStackTop = pStackTop->next;
pTmpStackNode->next->next = NULL;
}
while (pStackTop != pStackBottom)
{
pTmpStackNode = pStackTop;
pStackTop = pStackTop->next;
printf("code error!!n");
free(pTmpStackNode);
}
free(pStackBottom);
return ;
}



