题目
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 ^5
5
) 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.
题目大意
反转单链表,给定常数K和单链表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.
输入说明:每次输入一个案例,对每个案例,第一行内容是链表第一个节点的地址,节点数N(N<=100,000)(不一定是最终形成的单链表的节点数),常数K(<=N),K是需要反转的子链表的长度,节点的地址是一个5位的非负整数,NULL用-1来代替。
下面输入N行 格式如下:
Address Data Next
Address代表节点的位置,Data是整型数字,Next是下一个节点的位置。
解题思路
参考大神博客发现并不是链表题都必须要用链表结构去做,要多思考,先观察,逆序后不变的地方是前两组数据,即每个结点的 Address 和 data 是不变的,继续观察,其实当前结点的 next 是下一个结点的 Address
我们考虑将 Address 和 data 存起来,还要体现它们的关系,可以用数组 Data[Address] = data,同样的,我们可以将 next 和 Address 也以这种形式存储,即 Next[Address] = next
这样存储的结果是,知道 Address 我们可以通过 Data[ ] 数组找到对应 data,可以通过 Next[ ] 数组找到对应的 next
这样存储后,我们再把整个链表“理顺”,给出的 first node 即为第一个 Address,Next[first node] 是下一个结点的 Address,再用一个数组 list[ ] 把每次遇到的 Address 记录下来
到此为止我们有了能根据 Address 找到其他数据的关系数组,也有顺序记录 Address 的数组,问题就从"反转链表"简化为了"反转 Address"
再以每 K 个结点为区间,反转 list[ ] 数组中存储的 Address,再根据 Address 和其他数据的关系,就能完整地输出链表了!
代码
// 反转链表1.0.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include<iostream>
#include< iomanip>
#define MAXSIZE 100005
using namespace std;
int main()
{
int *Data = new int[MAXSIZE];
int *Next = new int[MAXSIZE];
int *List = new int[MAXSIZE];
int FirstAdd, N, K;
cin >>FirstAdd >> N >> K;
for (int i = 0; i < N; i++)
{ int tempadd, tempdata, tempnext;
cin >> tempadd >> tempdata >> tempnext;
Data[tempadd] = tempdata;
Next[tempadd] = tempnext;
}
int sum=0;
while (FirstAdd != -1)
{
List[sum++] = FirstAdd;
FirstAdd = Next[FirstAdd];
}
for (int i = 0; i < sum - sum%K; i+= K)
{
for (int j = 0; j < K / 2; j++)
{
int t = List[i+j];
List[i + j] = List[i + K - 1 - j];
List[i + K - 1 - j] = t;
}
}
for (int i = 0; i < sum - 1; i++)
{
printf("%05d %d% 05d\n", List[i], Data[List[i]], List[i + 1]);
}
cout << List[sum - 1] << " " << Data[List[sum - 1]] << " " << -1 << endl;
return 0;
}
注意
一开始直接创建三个整形数组,每个长度为10005,结果发现出错,直接栈溢出,后来改用利用New在堆上创不会受空间限制,建数组则没有问题。