反转链表数组排序写法

今天做算法笔记上的题目又碰到了反转链表。题目不难,但是写起来就是感觉脑子有点绕,也可能只是我水平太差的原因。

这已经是我第三次碰到这道题了,第一次是大一下开学期末考的时候,当时在机房写了一个多小时,我自己测试都是对的,而且基本上考虑到了所有的情况,但是每次提交都有几个测试点通不过,甚至还换了一种方法重新写了一遍还是不过,当时真的感觉心态有点崩了。

考完了之后还是不服,把题目重新看了一下,才发现题目上说是带有头结点的链表。。。我真的是要脑溢血了,上课的时候老师还在强调不要用头结点,平时作业也没有用过头结点,考试的时候出一道带有头结点的题,我根本没注意到。不过这样也好,从此以后看题目就更加注重这种细节了。

第二次写这题是上个学期后半学期没事练算法题的时候写到的。当时还没有写过静态链表,看到这道题目可以这样做就自己试了一下。虽然是写过,但是换一种方法就感觉是完全不一样的题目了,当时也是写了很久,画满了半张草稿纸。虽然最后代码量不大,但是写这种链表题总是感觉很绕。

今天是第三次写到这道题了,在书上学到了另外一种方法,就是把整个表示静态链表的数组进行排序,然后只要倒着输出就行了,太妙了。

1074 Reversing Linked List (25point(s))

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:

1
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:

1
2
3
4
5
6
7
00100 6 4
00000 4 99999
00100 1 12309
68237 6 -1
33218 3 00000
99999 5 68237
12309 2 33218

Sample Output:

1
2
3
4
5
6
00000 4 33218
33218 3 12309
12309 2 00100
00100 1 99999
99999 5 68237
68237 6 -1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#include <iostream>
#include <algorithm>
using namespace std;

const int maxn = 100010;
struct Node
{
int address, data, next;
int order = maxn; //结点在链表上的序号,无效标为maxn
}node[maxn];

bool cmp(Node a, Node b);


int main(int argc, const char * argv[])
{
int begin, n, k, address;
scanf("%d%d%d", &begin, &n, &k);
for(int i = 0; i < n; i++)
{
scanf("%d", &address);
scanf("%d%d", &node[address].data, &node[address].next);
node[address].address = address;
}
int p = begin, count = 0;
while(p != -1)
{
node[p].order = count++;
p = node[p].next;
}

sort(node, node + maxn, cmp);

n = count;
for(int i = 0; i < n / k; i++)
{
for(int j = (i + 1) * k - 1; j > 1; j--) //第i块倒着输出
printf("%05d %d %05d\n", node[j].address, node[j].data, node[j - 1].address);
printf("%05d %d ", node[i * k].address, node[i * k].data);
if(i < n / k - 1)
printf("%05d\n", node[(i + 2) * k - 1].address);
else
{
if(n % k == 0) //恰好是最后一个
printf("-1\n");
else //剩下的不完整块按原先顺序输出
{
printf("%05d\n", node[(i + 1) * k].address);
for(int i = n / k * k; i < n; i++)
{
printf("%05d %d ", node[i].address, node[i].data);
if(i < n - 1)
printf("%05d\n", node[i + 1].address);
else
printf("-1\n");
}
}

}
}

return 0;
}

bool cmp(Node a, Node b)
{
return a.order < b.order;
}

这种方法也是今天第一次学到,给我的最大的感触就是我以前写题目太老实了,可以从很多的角度来看题目,换一种方法直接边水题。

顺便写一下我以前写这道题的代码,我自我感觉还是写的不错的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#include <iostream>
#include <cstdlib>
using namespace std;

struct Node
{
int data;
int next;
}List[100001];

void Reversing(int start, int K);

int main(int argc, const char *argv[])
{
int First, N, K;
scanf("%d%d%d", &First, &N, &K);
for(int i = 0; i < N; i++)
{
int add;
scanf("%d", &add);
scanf("%d%d", &List[add].data, &List[add].next);
}
List[100000].next = First;

Reversing(100000, K);

int p = List[100000].next;
while(p != -1)
{
printf("%05d %d ", p, List[p].data);
if(List[p].next == -1)
printf("%d\n", List[p].next);
else
printf("%05d\n", List[p].next);
p = List[p].next;
}

return 0;
}

void Reversing(int start, int K)
{
int p, cnt = 0;
p = List[start].next;
cnt = 0;
while(p != -1)
{
p = List[p].next;
cnt++;
if(cnt == K)
{
int q1, q2, tmphead = List[start].next;
q2 = List[start].next;
q1 = List[q2].next;
for(int i = 0; i < K - 1; i++)
{
int tmp = List[q1].next;
List[q1].next = q2;
q2 = q1;
q1 = tmp;
}
List[List[start].next].next = q1;
List[start].next = q2;
start = tmphead;
cnt = 0;
}
}
}
作者

Jhuoer Yen

发布于

2021-01-28

更新于

2023-09-18

许可协议

评论

Your browser is out-of-date!

Update your browser to view this website correctly.&npsb;Update my browser now

×