刷题总结
存储链表的方式
// 数组模拟的方式
h; // 头结点
e[N], ne[N]; // 权值和指针
对链表变换方式
使用数组存储链表变化的地址
总体评价:PAT中的链表题目套路很明显,难度适中。
不需要像LeetCode去优化时间复杂度,考试时只需要好写即可。
PAT1032:共享
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 100010;
int ne[N], h1, h2, n;
char e[N];
bool st[N];
int main()
{
scanf("%d %d %d", &h1, &h2, &n);
for (int i = 0; i < n; i ++ )
{
int add, next;
char w;
scanf("%d %c %d", &add, &w, &next);
e[add] = w, ne[add] = next;
}
for (int i = h1; ~i; i = ne[i])
st[i] = true;
for (int i = h2; ~i; i = ne[i])
if(st[i])
{
printf("%05d", i);
return 0;
}
cout << -1 << endl;
return 0;
}
PAT1074:反转链表
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int N = 100010;
int h, n, m;
int e[N], ne[N];
vector<int> f;
int main()
{
cin >> h >> n >> m;
for (int i = 0; i < n; i ++ )
{
int add, data, next;
scanf("%d%d%d", &add, &data, &next);
e[add] = data, ne[add] = next;
}
for (int i = h; ~i; i = ne[i]) f.push_back(i);
for (int i = 0; i + m - 1 < f.size(); i += m )
reverse(f.begin() + i, f.begin() + m + i);
for (int i = 0; i < f.size(); i ++ )
{
printf("%05d %d ", f[i], e[f[i]]);
if(i == f.size() - 1) cout << -1 << endl;
else printf("%05d\n", f[i + 1]);
}
return 0;
}
PAT1097:链表重复数据删除
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <unordered_set>
using namespace std;
const int N = 100010;
int h, n;
int e[N], ne[N];
bool st[N];
int main()
{
cin >> h >> n;
for (int i = 0; i < n; i ++ )
{
int add, data, next;
scanf("%d %d %d", &add, &data, &next);
e[add] = data, ne[add] = next;
}
vector<int> res, ans;
for (int i = h; ~i; i = ne[i])
{
int j = abs(e[i]);
if(st[j]) ans.push_back(i);
else
{
st[j] = true;
res.push_back(i);
}
}
for (int i = 0; i < res.size(); i ++ )
{
printf("%05d %d ", res[i], e[res[i]]);
if(i == res.size() - 1) puts("-1");
else printf("%05d\n", res[i + 1]);
}
for (int i = 0; i < ans.size(); i ++ )
{
printf("%05d %d ", ans[i], e[ans[i]]);
if(i == ans.size() - 1) puts("-1");
else printf("%05d\n", ans[i + 1]);
}
return 0;
}
PAT1133:链表元素分类
三遍循环
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int N = 100010;
int h, n, k;
int e[N], ne[N];
int main()
{
cin >> h >> n >> k;
for (int i = 0; i < n; i ++ )
{
int add, data, next;
scanf("%d %d %d", &add, &data, &next);
e[add] = data, ne[add] = next;
}
vector<int> res;
for (int i = h; ~i; i = ne[i])
{
int j = e[i];
if(j < 0) res.push_back(i);
}
for (int i = h; ~i; i = ne[i])
{
int j = e[i];
if(j >= 0 && j <= k) res.push_back(i);
}
for (int i = h; ~i; i = ne[i])
{
int j = e[i];
if(j > k) res.push_back(i);
}
for (int i = 0; i < res.size(); i ++ )
{
printf("%05d %d ", res[i], e[res[i]]);
if(i == res.size() - 1) puts("-1");
else printf("%05d\n", res[i + 1]);
}
return 0;
}
三个数组拼接
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int N = 100010;
int h, n, k;
int e[N], ne[N];
int main()
{
cin >> h >> n >> k;
for (int i = 0; i < n; i ++ )
{
int add, data, next;
scanf("%d %d %d", &add, &data, &next);
e[add] = data, ne[add] = next;
}
vector<int> a, b, c;
for (int i = h; ~i; i = ne[i])
{
int j = e[i];
if(j < 0) a.push_back(i);
else if(j <= k) b.push_back(i);
else c.push_back(i);
}
a.insert(a.end(), b.begin(), b.end());
a.insert(a.end(), c.begin(), c.end());
for (int i = 0; i < a.size(); i ++ )
{
printf("%05d %d ", a[i], e[a[i]]);
if(i == a.size() - 1) puts("-1");
else printf("%05d\n", a[i + 1]);
}
return 0;
}