7-21 链表去重

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

输入格式:

输入在第一行给出 L 的第一个结点的地址和一个正整数 N(≤105,为结点总数)。一个结点的地址是非负的 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

思路:其实就是一个和上个那个链表重排差不多的题目,一开始博主想用一般链表去重,也就是删除的原理(就是上一个结点的指针连到下一个结点的next指针上面)但是不知道为什么有三个测试点没过,后来想想其实只是需要将一个去重之后的存到一个数组里面,一个重复的存另一个数组里面其实就可以了,直接输出。 

 

#include "bits/stdc++.h"
using namespace std;
const int N  = 1e5 + 10; 
string s[N], nex[N];
int a[N], vis[N];
map<string , int> mp; 
vector<int> v, w, h; 
int main(){
	string ss;
	int n, begin;
	string start = ss;
	cin>>ss>>n;
	for(int i = 0; i < n; i++){
		cin>>s[i]>>a[i]>>nex[i];
		mp[s[i]] = i;
		if(s[i] == ss) begin = i;
	}
	int now = begin;
	while(ss != "-1"){
		v.push_back(now);
		ss = nex[now];
		now = mp[nex[now]];
	}
	int sizev = v.size();
	int pre;
	for(int i = 0; i < v.size(); i ++){
		int t = abs(a[v[i]]);
		if(!vis[t]) {
			vis[t] = 1;	
			h.push_back(v[i]);
		}
		else {
			sizev --;
//			cout<<nex[pre] <<" " <<a[pre]<<" "<<nex[v[i]]<<"&&&"<<endl;
			w.push_back(v[i]);
			nex[pre] = nex[v[i]];
			//nex[mp[nex[v[i]]]];//这是下一个结点的next 
		} 
		pre = v[i];
	}
	now = begin;
	ss = start;
//	for(int i = 0; i < v.size(); i ++){
//		int t = abs(a[v[i]]);
//		if(!vis[t]) {
//			vis[t] = 1;	
//			
//		}
//	}
	for(int i = 0; i < h.size();  i++){
		cout<<s[h[i]]<<" "<<a[h[i]]<<" ";
		if(i != h.size() - 1) cout<<s[h[i + 1]]<<endl;
		else cout<<"-1"; 
	}
//	while(ss != "-1"){
//		cout<<s[now]<<" "<<a[now]<<" "<<nex[now];
//		ss = nex[now];
//		now = mp[nex[now]];
//		if(ss != "-1") cout<<endl; 
//	}
	if(w.size() != 0) cout<<endl;
	for(int i = 0; i < w.size();  i++){
		cout<<s[w[i]]<<" "<<a[w[i]]<<" ";
		if(i != w.size() - 1) cout<<s[w[i + 1]]<<endl;
		else cout<<"-1"; 
	}
	return 0;
}

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小竹子14

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值