1025. 反转链表 (25)
1025. 反转链表 (25)
Given a constant KK and a singly linked list LL, you are supposed to reverse the links of every KK elements on LL. For example, given LL being 1→2→3→4→5→6, if K = 3K=3, then you must output 3→2→1→6→5→4; if K = 4K=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 NN (\le 10^5≤10
5
) which is the total number of nodes, and a positive KK (\le N≤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 NN 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
给定一个常数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
这道题困恼了我一下午,从最开始的全部用数组下标表示,到后来发现用数组存储输入数据,用vector存储实际应有的数据既能内存避免开销有能减少时间,算是一个折中方案;当把数据存在了vector中后,就可以进行翻转了,这里直接用了STL:reverse(),有好用的算法为何不用呢!一切都变得很简单了对吧。
在做题过程中遇到了几个坑,在这跟大家分享一下:
1.不要全部都用数组表示,这样空间花销太大,而且也很难进行反转;
2.输入的数据节点有可能不是有效的节点,所以要重新计算链表长度(大坑,想了两三个小时才想到);
3.反转后将最后一个节点的next置于-1;
第一版代码:思路是清晰就是太啰嗦
#include<iostream>
#include<iomanip>
#include<vector>
#include<algorithm>
using namespace std;
//通过数组初始化读入链表,地址用数组下标表示
struct Node {
int addr;
int next;
int data;
}node[100001];
//将所有节点按序保存在向量中
vector<Node>v1;
vector<Node>::iterator iter;
int main()
{
int head, N, K;
int count=0,c=0;
int t_addr, t_data, t_next;
Node n;
cin >> head >> N >> K;
if (head == -1) {
cout << -1 << endl;
return 0;
}
for (int i = 0; i<N; i++) {
cin >> t_addr >> t_data >> t_next;
node[t_addr].addr = t_addr;
node[t_addr].data = t_data;
node[t_addr].next = t_next;
}
n = node[head];
int size;
for (size = 1; n.next != -1; n = node[n.next]) {
//将节点保存在v1中,并按照每个节点连续,
//size记录有效节点的个数,不直接用v1.size()是因为这样调用时间花费太大
v1.push_back(n); size++;
}
v1.push_back(n);
if (K != 1) {//若K!=1则开始反转
for (int c = 0; size >= K; c++) {//c用来记录反转的次数,便于每次设置反转的位置
reverse(v1.begin() + c*K, v1.begin() + (c + 1)*K);
size -= K;
}
}
//调整每个节点的next地址;
for (iter = v1.begin(); iter != v1.end(); iter++) {
if (iter + 1 == v1.end()) {
Node &y = *iter;
y.next = -1;
}else{
Node &x = *iter;
Node &y = *(iter + 1);
x.next = y.addr;
}
}
//输出节点
for (iter = v1.begin(); iter != v1.end(); iter++) {
n = *iter;
if (iter + 1 < v1.end())
cout << setfill('0') << setw(5) << n.addr << ' ' << n.data << ' ' << setfill('0') << setw(5) << n.next << endl;
else {
cout << setfill('0') << setw(5) << n.addr << ' ' << n.data<< ' '<<n.next << endl;
}
}
return 0;
}
第二版代码:觉得优化的不错了,如果还有优化之处的欢迎联系评论
#include<iostream>
#include<iomanip>
#include<vector>
#include<algorithm>
using namespace std;
struct Node {
int next;
int data;
}node[100010];
int main()
{
int head, N, K;
vector<int> list;
int t_addr, t_data, t_next;
cin >> head >> N >> K;
if (head == -1) {
cout << -1 << endl;
return 0;
}
for (int i = 0; i < N; i++)
{
cin >> t_addr >> t_data >> t_next;
node[t_addr].data = t_data;
node[t_addr].next = t_next;
}
int size = 0;
int p = head;
while (head != -1)
{
list.push_back(head);
head = node[head].next;
}
size = list.size();
int i = 0;
while (i + K <= size)
{
reverse(&list[i], &list[i + K]);
i = i + K;
}
for (i = 0; i < size - 1; i++)
cout << setfill('0') << setw(5) << list[i] << ' ' << node[list[i]].data << ' ' << setfill('0') << setw(5) << list[i + 1] << endl;
cout << setfill('0') << setw(5) << list[i] << ' ' << node[list[i]].data << ' ' << "-1" << endl;
return 0;
}