题目
Given a constant K and a singly linked list L, you are supposed to reverse the links of every K elements on L. For example, given L being 1→2→3→4→5→6, if K=3, then you must output 3→2→1→6→5→4; if K=4, you must output 4→3→2→1→5→6.
Input Specification:
Each input file contains one test case. For each case, the first line contains the address of the first node, a positive N (≤105) which is the total number of nodes, and a positive K (≤N) which is the length of the sublist to be reversed. The address of a node is a 5-digit nonnegative integer, and NULL is represented by -1.
Then N lines follow, each describes a node in the format:
Address Data Next
where Address
is the position of the node, Data
is an integer, and Next
is the position of the next node.
Output Specification:
For each case, output the resulting ordered linked list. Each node occupies a line, and is printed in the same format as in the input.
Sample Input:
00100 6 4
00000 4 99999
00100 1 12309
68237 6 -1
33218 3 00000
99999 5 68237
12309 2 33218
Sample Output:
00000 4 33218
33218 3 12309
12309 2 00100
00100 1 99999
99999 5 68237
68237 6 -1
运行结果
Case | Hint | Result | Run Time | Memory |
---|---|---|---|---|
0 | sample 有尾巴不反转, 地址取上下界 | Accepted | 2 ms | 352 KB |
1 | 正好全反转 | Accepted | 3 ms | 352 KB |
2 | K=N全反转 | Accepted | 3 ms | 416 KB |
3 | K=1不用反转 | Accepted | 2 ms | 416 KB |
4 | N=1 最小case | Accepted | 2 ms | 384 KB |
5 | 最大N,最后剩K-1不反转 | Accepted | 153 ms | 6048 KB |
6 | 有多余结点不在链表上 | Accepted | 3 ms | 416 KB |
总结:程序占用的内存稍多,还可以继续改进,有看到更好的运行结果:
http://www.pianshen.com/article/2800296730/
程序
#include<iostream>
using namespace std;
typedef struct node *PtrToNode;
struct node
{
int adress;
int data;
int nextAdress;
PtrToNode next;
};
typedef PtrToNode List;
int MAX_ADRESS = 100000;
//真实链表长度
int TrueN = 0;
List read(int firstAdress, int N, int K);
void printList(List L);
List read_test(int firstAdress, int N, int K);
List reverseKsublist(List L, int N, int K);
int main()
{
List L, newL;
int firstAdress, N, K;
cin >> firstAdress;
cin >> N;
cin >> K;
L = read(firstAdress, N, K);
/* 测试用例
firstAdress = 100;
N = 7;
K = 7;
L = read_test(firstAdress, N, K);
*/
newL = reverseKsublist(L, TrueN, K);
printList(newL);
return 0;
}
List reverSubList(List subList, int K)
{
List FirstToL, SecToL, ThreeToL;
FirstToL = subList->next;
SecToL = FirstToL->next;
ThreeToL = NULL;
for(int i=0; i<K-1; i++){
ThreeToL = SecToL->next;
SecToL->next = FirstToL;
SecToL->nextAdress = FirstToL->adress;
//三个指针后移
FirstToL = SecToL;
SecToL = ThreeToL;
}
//将反转后的最后一个元素接到下一个链表第一个元素
subList->next->next = SecToL;
if(ThreeToL){
subList->next->nextAdress = SecToL->adress;
}
else{
subList->next->nextAdress = -1;
}
subList->next = FirstToL;
subList->nextAdress = FirstToL->adress;
return subList;
}
List reverseKsublist(List L, int N, int K)
{
List newSubList, temp;
if(K == 1){return L;}
if(K>N){K=N;}
List subListHead = L;
for(int i=0; i<N/K; i++){
newSubList = reverSubList(subListHead, K);
for(int j=0; j<K; j++)
{subListHead = subListHead->next;}
}
return L;
}
//测试用例
List read_test(int firstAdress, int N, int K)
{
int data[MAX_ADRESS];
int next[MAX_ADRESS];
int tempAdr;
List L, tempL, temp;
L = new node;
L->nextAdress = firstAdress;
L->next = NULL;
tempL = L;
//以数据地址作为数组的索引
//1
tempAdr = 0;
data[tempAdr] = 4;
next[tempAdr] = 99999;
//2
tempAdr = 100;
data[tempAdr] = 1;
next[tempAdr] = 12309;
//3
tempAdr = 68237;
data[tempAdr] = 6;
next[tempAdr] = -1;
//4
tempAdr = 33218;
data[tempAdr] = 3;
next[tempAdr] = 0;
//5
tempAdr = 99999;
data[tempAdr] = 5;
next[tempAdr] = 68237;
//6
tempAdr = 12309;
data[tempAdr] = 2;
next[tempAdr] = 33218;
//7 ->多余结点,不会出现在链表上的
tempAdr = 00002;
data[tempAdr] = 10;
next[tempAdr] = 25468;
//构建链表结构
while(1)
{
++TrueN;
temp = new node;
if(next[tempL->nextAdress] == -1){
temp->adress = tempL->nextAdress;
temp->data = data[temp->adress];
temp->nextAdress = next[temp->adress];
temp->next = NULL;
tempL->next = temp;
tempL = tempL->next;
tempL->next = NULL;
break;
}
temp->adress = tempL->nextAdress;
temp->data = data[temp->adress];
temp->nextAdress = next[temp->adress];
tempL->next = temp;
tempL = tempL->next;
}
//printList(L);
return L;
}
List read(int firstAdress, int N, int K)
{
int data[MAX_ADRESS];
int next[MAX_ADRESS];
int tempAdr;
List L, tempL, temp;
L = new node;
L->nextAdress = firstAdress;
L->next = NULL;
tempL = L;
//以数据地址作为数组的索引
for(int i=0; i<N; i++)
{
cin >> tempAdr;
cin >> data[tempAdr];
cin >> next[tempAdr];
}
//构建链表结构
while(1)
{
++TrueN;
temp = new node;
if(next[tempL->nextAdress] == -1){
temp->adress = tempL->nextAdress;
temp->data = data[temp->adress];
temp->nextAdress = next[temp->adress];
temp->next = NULL;
tempL->next = temp;
tempL = tempL->next;
tempL->next = NULL;
break;
}
temp->adress = tempL->nextAdress;
temp->data = data[temp->adress];
temp->nextAdress = next[temp->adress];
tempL->next = temp;
tempL = tempL->next;
}
//printList(L);
return L;
}
void printList(List L)
{
List tempL;
tempL = L->next;
while(tempL)
{
if(tempL->nextAdress == -1)
printf("%.5d %d %d\n", tempL->adress, tempL->data, tempL->nextAdress);
else
//格式输出,%.5意味着如果一个整数不足5位,输出时前面补0 如:22,输出:00022
printf("%.5d %d %.5d\n", tempL->adress, tempL->data, tempL->nextAdress);
tempL = tempL->next;
}
}