【来源】
【分析】
题目给出一系列链表的节点,要求将链表中每K个节点翻转。最后不到K个元素不反转。
和本题类似的题目有:Advanced Level 中的 1052. Linked List Sorting (25),处理的思路是一样的。
对这种地址空间较小的题目,通用的做法是开一个大一点的Vector,然后把Vector的index映射为节点的地址。这样处理起来速度较快。
另外,处理的过程中无需考虑节点Next的值的正确性。处理完毕后从头遍历链表节点修改Next指针即可。
步骤大致如下:
- 从头节点开始,先找出整条链表,用Vector按顺序存放(注意有的节点可能不包含在链表中的情况);
- 从头开始每K个节点将这些节点倒序输入到新的Vector中;
- 如果整条链表节点个数不是K的整数倍,需要把剩余的节点按原来的顺序输入到新的Vector;
- 修改节点的Next指针:遍历节点,把当前节点的Next指针值设为下个节点的Address;
- 输出。
需要注意的是链表头地址为-1的情况,另外不要忘了修改最后一个节点的Next指针为-1。
【代码】
#include <iostream> #include <cstdio> #include <vector> using namespace std; struct Node{ int addr; int value; int next; }; int main() { int FirstAddr, N, K; scanf("%d%d%d", &FirstAddr, &N, &K); vector<Node> nodes(100000); for(int i = 0; i < N; ++i){ Node node; scanf("%d%d%d", &node.addr, &node.value, &node.next); nodes[node.addr] = node; } if(FirstAddr == -1){ printf("-1\n"); } else{ vector<Node> aftersort; int NextAddr = FirstAddr; while(NextAddr != -1){ aftersort.push_back(nodes[NextAddr]); NextAddr = nodes[NextAddr].next; } vector<Node> final; int lastindex = K-1; while(lastindex < aftersort.size()){ for(int i = lastindex; i > lastindex-K; --i){ final.push_back(aftersort[i]); } lastindex += K; } for(int i = lastindex-K+1; i < aftersort.size(); ++i){ final.push_back(aftersort[i]); } for(int i = 0; i < final.size()-1; ++i){ final[i].next = final[i+1].addr; } int i; for(i = 0; i < final.size()-1; ++i){ printf("%05d %d %05d\n", final[i].addr, final[i].value, final[i].next); } printf("%05d %d %d\n", final[i].addr, final[i].value, -1); } system("pause"); return 0; }
【点评】
此题为2014.3.1 PAT 春季考试最后一题,考察链表的相关知识,稍难。不过只要思路正确,也是很快可以写出AC的代码的。