PAT甲级1133Splitting A Linked List

题目链接

https://pintia.cn/problem-sets/994805342720868352/problems/994805346776760320

题解

题目要求

给1个有n(不超过1e5)个结点的单向链表和数字k(不超过1e3),链表的值属于[-1e5,1e5]要求将链表改为(或输出):负数结点出现在正数结点之前,值属于[0,k]的结点出现在值大于k的结点之前,其余不变##

注意点

  • PAT中的这种链表适合用数组形式的链表
  • PAT里的链表和LeetCode里的链表(LeetCode里的链表是基于指针的)不太一样,因此操作也要适当调整
  • 不一定要修改链表结构,能按要求输出就可以

思路

用数组表示链表,然后遍历将链表里的结点分成3类(小于0的、0到k的、大于k的)并存入3个数组,然后按顺序遍历3个数组并输出

代码

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
// Problem: PAT Advanced 1133
// URL: https://pintia.cn/problem-sets/994805342720868352/problems/994805346776760320
// Tags: Linked List

#include <iostream>
#include <vector>
using namespace std;

struct ListNode{
int val;
int next;
};

ListNode list[int(1e5) + 10];
vector<int> parts[3];

int main()
{
// 获取输入
int head, n, k; // 头结点地址、结点数量、k
cin >> head >> n >> k;
int address;
for (int i = 0; i < n; i++){
cin >> address;
cin >> list[address].val >> list[address].next;
}

// 遍历链表将其中的结点分为3个部分
int p = head;
while(p != -1){
int partIndex = 1; // 默认为第2部分,即结点的值属于[0,k]
if (list[p].val < 0)
partIndex = 0;
else if(list[p].val > k)
partIndex = 2;
parts[partIndex].push_back(p);
p = list[p].next;
}

// 将划分好的3部分结点输出
bool isFirstLine = true;
for (int i = 0; i < 3; i++){
for (int j = 0; j < parts[i].size(); j++){
if (isFirstLine){
printf("%05d %d", parts[i][j], list[parts[i][j]].val);
isFirstLine = false;
}
else
printf(" %05d\n%05d %d", parts[i][j], parts[i][j], list[parts[i][j]].val);
}
}
cout << " -1";
return 0;
}

作者:@臭咸鱼

转载请注明出处:https://www.cnblogs.com/chouxianyu/

欢迎讨论和交流!