L2-002 链表去重 模拟

L2-002 链表去重 (25 分)


给定一个带整数键值的链表 L,你需要把其中绝对值重复的键值结点删掉。即对每个键值 K,只有第一个绝对值等于 K 的结点被保留。同时,所有被删除的结点须被保存在另一个链表上。例如给定 L211515715,你需要输出去重后的链表 21157,还有被删除的链表 1515


输入格式

输入在第一行给出 L 的第一个结点的地址和一个正整数 N105,为结点总数)。一个结点的地址是非负的 5 位整数,空地址 NULL 用 1 来表示。

随后 N 行,每行按以下格式描述一个结点:

地址 键值 下一个结点

其中地址是该结点的地址,键值是绝对值不超过104的整数,下一个结点是下个结点的地址。


输出格式

首先输出去重后的链表,然后输出被删除的链表。每个结点占一行,按输入的格式输出。


输入样例

00100 5
99999 -7 87654
23854 -15 00000
87654 15 -1
00000 -15 99999
00100 21 23854

输出样例

00100 21 23854
23854 -15 99999
99999 -7 -1
00000 -15 87654
87654 15 -1

作者:陈越
单位:浙江大学
代码长度限制:16 KB
时间限制:400 ms
内存限制:64 MB



Solution

思路来自跃鱼的 L2-002 链表去重 (25分)

1.直接用 结构体数组 保存链表信息;

2.注意到只需要判断 键值的绝对值 是否出现过,使用vis[]记录即可;

3.用另外两个 结构体数组 保存去重后的链表、被删除的链表;

4.这样就不用考虑维护链表的下一个地址,因为下一个地址就是 结构体数组中 下一个结构体 保存的地址;

5.注意每个链表末尾都 链接 空地址 即可;


Solution

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std;
const int N=100005;
struct node{
	int now,w,nxt;
}list[N],ans1[N],ans2[N];
bool vis[N];
int ST,n,cnt1,cnt2;
int main(){
	scanf("%d %d",&ST,&n);
	for(int now,w,nxt,i=1;i<=n;++i){
		scanf("%d %d %d",&now,&w,&nxt);
		list[now].now=now;
		list[now].w=w;
		list[now].nxt=nxt;
	}
	for(int i=ST;i!=-1;i=list[i].nxt){
		if(!vis[abs(list[i].w)]){
			vis[abs(list[i].w)]=1;
			ans1[++cnt1]=list[i];
		} else 
			ans2[++cnt2]=list[i];
	}
	for(int i=1;i<=cnt1;++i){
		if(i!=cnt1) printf("%05d %d %05d\n",ans1[i].now,ans1[i].w,ans1[i+1].now);
		else printf("%05d %d %d\n",ans1[i].now,ans1[i].w,-1);
	}
	for(int i=1;i<=cnt2;++i){
		if(i!=cnt2) printf("%05d %d %05d\n",ans2[i].now,ans2[i].w,ans2[i+1].now);
		else printf("%05d %d %d\n",ans2[i].now,ans2[i].w,-1);
	}
	return 0;
}
posted @   PotremZ  阅读(522)  评论(0编辑  收藏  举报
编辑推荐:
· DeepSeek 解答了困扰我五年的技术问题
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 用 C# 插值字符串处理器写一个 sscanf
· Java 中堆内存和栈内存上的数据分布和特点
· 开发中对象命名的一点思考
阅读排行:
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· DeepSeek 解答了困扰我五年的技术问题。时代确实变了!
· 本地部署DeepSeek后,没有好看的交互界面怎么行!
· 趁着过年的时候手搓了一个低代码框架
· 推荐一个DeepSeek 大模型的免费 API 项目!兼容OpenAI接口!
点击右上角即可分享
微信分享提示