给定一个常数 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 个元素不反转。
输入格式:
每个输入包含 1 个测试用例。每个测试用例第 1 行给出第 1 个结点的地址、结点总个数正整数 N (≤105)、以及正整数 K (≤N),即要求反转的子链结点的个数。结点的地址是 5 位非负整数,NULL 地址用 −1 表示。
接下来有 N 行,每行格式为:
Address Data Next
其中 Address
是结点地址,Data
是该结点保存的整数数据,Next
是下一结点的地址。
输出格式:
对每个测试用例,顺序输出反转后的链表,其上每个结点占一行,格式与输入相同。
输入样例:
00100 6 4
00000 4 99999
00100 1 12309
68237 6 -1
33218 3 00000
99999 5 68237
12309 2 33218
输出样例:
00000 4 33218
33218 3 12309
12309 2 00100
00100 1 99999
99999 5 68237
68237 6 -1
思路:
这个题是真的坑,题目没有说清楚有可能会存在不属于 L 上的节点,这样就导致输出的节点可能会比输入的节点要少,所以可以用 map 记录好首地址和值和下一节点对应关系后,将该条链表所有的节点地址放入一个数组中(不使用 map 直接用数组 hash 存储也是可以的)。其次是一定要记得最后链表逆转时对应的下一节点地址(Next)也会发生改变,在题目中就可以处理为直接输出下一节点的地址,而不是之前存储在 map 中当前地址和下一节点地址的对应关系。
代码:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <map>
using namespace std;
const int maxn = 1e5 + 7;
int res[maxn];
map<int, int> dat, nxt;
int main()
{
int a, n, k, tmp;
cin >> a >> n >> k;
int p, q;
for(int i = 0; i < n; i++){
cin >> tmp >> p >> q;
dat[tmp] = p;
nxt[tmp] = q;
}
int cnt = 0; //有可能存在不属于这条链表的节点
while(a != -1){
res[cnt++] = a;
a = nxt[a];
}
for(int i = 0; i < (cnt - cnt % k); i += k)
reverse(res + i, res + i + k);
for(int j = 0; j < cnt - 1; j++)
printf("%05d %d %05d\n", res[j], dat[res[j]], res[j + 1]); //此时输出的 Next 不再是之前的,而是重新链接后的
printf("%05d %d -1\n", res[cnt - 1], dat[res[cnt - 1]]);
return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)