题目链接
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个数组并输出
代码
// 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
%05d %d", parts[i][j], parts[i][j], list[parts[i][j]].val);
}
}
cout << " -1";
return 0;
}
作者:@臭咸鱼
转载请注明出处:https://www.cnblogs.com/chouxianyu/
欢迎讨论和交流!