L2-002 链表去重(c++,python)

给定一个带整数键值的链表 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

 分析:

用python里的字典和列表模拟一下链表就好啦,数据结构为{地址:[键值,下一个结点]}和[地址,键值,下一个结点],注意最后要更新一遍各结点的下一个结点地址。

测试点2:第二条链表为空,不输出

python代码(没有AC)

p, n = input().split()
n = int(n)
dic = {}  # 储存输入的数据{地址:[键值,下一个结点]}
for i in range(n):
    a, b, c = input().split()
    b = int(b)
    dic[a] = [b, c]

res1 = []
res2 = []
check = set()  # 查重

# 从p开始遍历字典并查重,第一次出现的加到res1,重复出现的加到res2
while p != '-1':
    if abs(dic[p][0]) not in check:
        check.add(abs(dic[p][0]))
        res1.append([p] + dic[p])
    else:
        res2.append([p] + dic[p])
    p = dic[p][1]

# 更新各结点的下一个结点地址
for i in range(len(res1) - 1):
    res1[i][2] = res1[i + 1][0]
res1[-1][2] = -1
for x in res1:
    print(*x)
for i in range(len(res2) - 1):
    res2[i][2] = res2[i + 1][0]
if res2:  # 如果res2为空就不用输出啦
    res2[-1][2] = -1
    for x in res2:
        print(*x)

运行超时啦!我们用c++来写一遍就好啦

c++代码

#include"iostream"
using namespace std;
struct Node {
	int address;
	int data;
	int next;
};
Node a[100005], b[100005], c[100005];
int main() {
	int check[10005] = { 0 };
	int first, n;
	cin >> first >> n;
	for (int i = 0;i < n;i++) {
		int add, da, ne;
		cin >> add >> da >> ne;
		a[add].address = add;
		a[add].data = da;
		a[add].next = ne;
	}
	int i = first;
	int cnt1 = 0, cnt2 = 0;
	while (1) {
		if (!check[abs(a[i].data)]) {
			check[abs(a[i].data)] = 1;
			if (cnt1 > 0)b[cnt1 - 1].next = a[i].address;
			b[cnt1].address = a[i].address;
			b[cnt1].data = a[i].data;
			b[cnt1++].next = -1;
		}
		else {
			if (cnt2 > 0)c[cnt2 - 1].next = a[i].address;
			c[cnt2].address = a[i].address;
			c[cnt2].data = a[i].data;
			c[cnt2++].next = -1;
		}
		if (a[i].next == -1)break;
		i = a[i].next;
	}
	for (i = 0;i < cnt1;i++) {
		if (b[i].next == -1)
			printf("%05d %d -1\n", b[i].address, b[i].data);
		else
			printf("%05d %d %05d\n", b[i].address, b[i].data, b[i].next);
	}
	for (i = 0;i < cnt2;i++) {
		if(c[i].next==-1)
			printf("%05d %d -1\n", c[i].address, c[i].data);
		else
			printf("%05d %d %05d\n", c[i].address, c[i].data, c[i].next);
	}
}

过啦~

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值