PAT Basic 1025. 反转链表
PAT Basic 1025. 反转链表
1. 题目描述:
给定一个常数 \(K\) 以及一个单链表 \(L\),请编写程序将 \(L\) 中每 \(K\) 个结点反转。例如:给定 \(L\) 为 \(1→2→3→4→5→6\),\(K\) 为 3,则输出应该为 \(3→2→1→6→5→4\);如果 \(K\) 为 4,则输出应该为 \(4→3→2→1→5→6\),即最后不到 \(K\) 个元素不反转。
2. 输入格式:
每个输入包含 1 个测试用例。每个测试用例第 1 行给出第 1 个结点的地址、结点总个数正整数 \(N\) (\(≤10^5\))、以及正整数 \(K\) (\(≤N\)),即要求反转的子链结点的个数。结点的地址是 5 位非负整数,NULL 地址用 −1 表示。
接下来有 \(N\) 行,每行格式为:
Address Data Next
其中 Address
是结点地址,Data
是该结点保存的整数数据,Next
是下一结点的地址。
3. 输出格式:
对每个测试用例,顺序输出反转后的链表,其上每个结点占一行,格式与输入相同。
4. 输入样例:
00100 6 4
00000 4 99999
00100 1 12309
68237 6 -1
33218 3 00000
99999 5 68237
12309 2 33218
5. 输出样例:
00000 4 33218
33218 3 12309
12309 2 00100
00100 1 99999
99999 5 68237
68237 6 -1
6. 性能要求:
Code Size Limit
16 KB
Time Limit
400 ms
Memory Limit
64 MB
思路:
定义一个结构体存储链表相关的信息,为了翻转链表,首先要知道各元素间的顺序关系,这里注释掉的部分是额外定义了一个元素order用于存储顺序信息,然后用qsort()库函数根据order排序,最后进行输出。另外一种思路就是直接额外定义一个输出用的结构体数组,因为输入数据的结点也是乱序的,所以在寻找原始链表时就可以按顺序将其存到额外的结构体数组中,两种做法相当于时间和空间的一个权衡。这里第一种做法,testpoint5一直timeout,之所以按顺序存储链表是为了方便输出。
这里另外一个bug点就是输入数据中的结点不保证一定在链表上(testpoint6)。
My Code:
// #include <stdio.h>
// #include <string.h>
// #include <stdlib.h>
// int cmpfunc (const void * a, const void * b);
// typedef struct node
// {
// char address[6];
// int data;
// char next[6];
// int order;
// } NODE;
// int main()
// {
// char headAddress[6];
// int nodeNum = 0, base = 0;
// NODE * ptNode;
// int currentNode = 0;
// int groupNum = 0, remainder = 0;
// int count = 0;
// scanf("%s%d%d", headAddress, &nodeNum, &base);
// ptNode = (NODE *)malloc(sizeof(NODE) * nodeNum);
// for(int i=0; i<nodeNum; i++)
// {
// scanf("%s%d%s", ptNode[i].address, &ptNode[i].data, ptNode[i].next);
// ptNode[i].order = nodeNum+1;
// }
// for(currentNode = 0; currentNode<nodeNum; currentNode++)
// {
// if(!strcmp(ptNode[currentNode].address, headAddress)) // strcmp return 0 when two string equal
// {
// ptNode[currentNode].order = 1;
// break;
// }
// }
// count = 1;
// while(strcmp(ptNode[currentNode].next, "-1")) // !!! testpoint6 should pay great attention, the node doesn't guarantee in List.
// {
// for(int i=0; i<nodeNum; i++)
// {
// if(ptNode[i].order == nodeNum+1 && !strcmp(ptNode[i].address,ptNode[currentNode].next))
// {
// count++;
// ptNode[i].order = count;
// currentNode = i;
// break;
// }
// }
// }
// // for(int i=1; i<nodeNum; i++)
// // {
// // for(int j=0; j<nodeNum; j++)
// // {
// // if(ptNode[j].order < 0 && !strcmp(ptNode[j].address,ptNode[currentNode].next))
// // {
// // ptNode[j].order = i;
// // currentNode = j;
// // break;
// // }
// // }
// // }
// // void qsort(void *base, size_t nitems, size_t size, int (*compar)(const void *, const void*))
// qsort(ptNode, nodeNum, sizeof(NODE), cmpfunc);
// groupNum = count / base;
// remainder = count % base;
// for(int i=1; i<=groupNum; i++)
// {
// for(int j=0; j<base; j++)
// {
// currentNode = i*base - j - 1;
// if(j==base-1)
// {
// if(i<groupNum)
// printf("%s %d %s\n", ptNode[currentNode].address, ptNode[currentNode].data, ptNode[(i+1)*base-1].address);
// else
// {
// if(remainder)
// printf("%s %d %s\n", ptNode[currentNode].address, ptNode[currentNode].data, ptNode[i*base].address);
// else
// printf("%s %d -1\n", ptNode[currentNode].address, ptNode[currentNode].data);
// }
// }
// else
// {
// printf("%s %d %s\n", ptNode[currentNode].address, ptNode[currentNode].data, ptNode[currentNode-1].address);
// }
// //printf("%s %d %s\n", ptNode[currentNode].address, ptNode[currentNode].data, ptNode[currentNode].next);
// // if(i==1&&j==0)
// // {
// // printf("%s %d ", ptNode[currentNode].address, ptNode[currentNode].data);
// // }
// // else
// // {
// // printf("%s\n%s %d ", ptNode[currentNode].address, ptNode[currentNode].address, ptNode[currentNode].data);
// // }
// }
// }
// if(remainder)
// {
// for(int i=remainder; i>0; i--)
// {
// currentNode = count - i;
// printf("%s %d %s\n", ptNode[currentNode].address, ptNode[currentNode].data, ptNode[currentNode].next);
// // printf("%s\n%s %d ", ptNode[currentNode].address, ptNode[currentNode].address, ptNode[currentNode].data);
// }
// }
// // printf("-1\n");
// free(ptNode);
// return 0;
// }
// int cmpfunc (const void * a, const void * b)
// {
// NODE * left = (NODE *) a;
// NODE * right = (NODE *) b;
// return (left->order - right->order);
// }
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct node
{
char address[6];
int data;
char next[6];
} NODE;
int main()
{
char headAddress[6];
int nodeNum = 0, base = 0;
NODE * ptNode;
int currentNode = 0;
int groupNum = 0, remainder = 0;
int count = 0;
NODE * out;
scanf("%s%d%d", headAddress, &nodeNum, &base);
ptNode = (NODE *)malloc(sizeof(NODE) * nodeNum);
out = (NODE *)malloc(sizeof(NODE) * nodeNum); // to solve testpoint5 run
for(int i=0; i<nodeNum; i++)
{
scanf("%s%d%s", ptNode[i].address, &ptNode[i].data, ptNode[i].next);
}
for(int i=0; i<nodeNum; i++)
{
if(!strcmp(ptNode[i].address, headAddress)) // strcmp return 0 when two string equal
{
out[count] = ptNode[i];
count++;
}
else if(count && !strcmp(ptNode[i].address, out[count-1].next))
{
out[count] = ptNode[i];
count++;
}
}
while(strcmp(out[count-1].next, "-1")) // !!! testpoint6 should pay great attention, the node doesn't guarantee in List.
{
for(int i=0; i<nodeNum; i++)
{
if(!strcmp(ptNode[i].address,out[count-1].next))
{
out[count] = ptNode[i];
count++;
break;
}
}
}
// qsort(ptNode, nodeNum, sizeof(NODE), cmpfunc);
groupNum = count / base;
remainder = count % base;
// printf("count: %d\n", count);
// printf("groupNum: %d\n", groupNum);
// printf("remainder: %d\n", remainder);
for(int i=1; i<=groupNum; i++)
{
for(int j=0; j<base; j++)
{
currentNode = i*base - j - 1;
if(j==base-1)
{
if(i<groupNum)
printf("%s %d %s\n", out[currentNode].address, out[currentNode].data, out[(i+1)*base-1].address);
else
{
if(remainder)
printf("%s %d %s\n", out[currentNode].address, out[currentNode].data, out[i*base].address);
else
printf("%s %d -1\n", out[currentNode].address, out[currentNode].data);
}
}
else
{
printf("%s %d %s\n", out[currentNode].address, out[currentNode].data, out[currentNode-1].address);
}
}
}
if(remainder)
{
for(int i=remainder; i>0; i--)
{
currentNode = count - i;
printf("%s %d %s\n", out[currentNode].address, out[currentNode].data, out[currentNode].next);
}
}
free(ptNode);
free(out);
return 0;
}