1097 Deduplication on a Linked List (25 point(s)) PAT甲级

1097 Deduplication on a Linked List (25 point(s))

链表

题目

Given a singly linked list L with integer keys, you are supposed to remove the nodes with duplicated absolute values of the keys. That is, for each value K, only the first node of which the value or absolute value of its key equals K will be kept. At the mean time, all the removed nodes must be kept in a separate list. For example, given L being 21→-15→-15→-7→15, you must output 21→-15→-7, and the removed list -15→15.

Input Specification:

Each input file contains one test case. For each case, the first line contains the address of the first node, and a positive N (≤105) which is the total number of nodes. The address of a node is a 5-digit nonnegative integer, and NULL is represented by −1.

Then N lines follow, each describes a node in the format:

Address Key Next

where Address is the position of the node, Key is an integer of which absolute value is no more than 104, and Next is the position of the next node.

Output Specification:

For each case, output the resulting linked list first, then the removed list. Each node occupies a line, and is printed in the same format as in the input.

Sample Input:

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

Sample Output:

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

思路

题意

给定n个地址的开始地址,乱序给出每个地址的key值和下一个地址值,串成一串链表。链表中不可以有重复绝对值的数存在,重复的出现的数会被归入另一个链表。按要求输出这两个链表。

分析

因为地址是5位数字构成的,可以直接用数组存储。因为key的绝对值小于 1 0 4 10^4 104,再用一个bool类来记录key的绝对值是否被访问过即可。构建node{key, next}来存储一开始的地址链表。用vector类ans来存储重复被排除的地址信息。根据给出的起始地址从头开始遍历,如果key的绝对值访问过了就把地址信息放到ans中,没有访问过则输出当前地址和key值。因为改变了链表结构,next值不能直接输出,而是下一个真正地址的addr值。所以除了起始地址,前一个地址的next值由当前地址输出。最后addr==-1跳出循环后再输出-1并换行。ans里的输出同理。

这个方法速度比较快,内存占用可能较多,代码也有点冗余,但是题目条件蛮宽松的,暴力解决也可以~

代码

#include<iostream>
#include<vector>
#include<math.h>
using namespace std;

struct node {
	int key, next;
};

struct node2 {
	int addr, key, next;
};

bool visit[10005] = { false };
node list[100005];

int main()
{
	int start, n, addr, key, next;
	scanf("%d%d", &start, &n);
	vector<node2> ans;
	for (int i = 0; i < n; ++i) {
		scanf("%d%d%d", &addr, &key, &next);
		list[addr].key = key;
		list[addr].next = next;
	}
	addr = start;
	while (addr != -1){
		if (visit[abs(list[addr].key)])
			ans.push_back({ addr,list[addr].key, list[addr].next });
		else {
			visit[abs(list[addr].key)] = true;
            if(addr != start)
                printf("%05d\n", addr);
			printf("%05d %d ", addr, list[addr].key);
		}
		addr = list[addr].next;
	}
	printf("-1\n");
    if(ans.size() == 0) return 0;			//不加如果没有重复值会输出多余的-1.也可以加载printf处判断
	for (int i = 0; i < ans.size(); ++i) {
		if (i != 0)
			printf("%05d\n", ans[i].addr);
		printf("%05d %d ", ans[i].addr, ans[i].key);
	}
	printf("-1\n");

	return 0;
}

注意

  • 地址可能没有重复的key值
  • 在循环外先把第一个输出的特殊情况写了代码冗余量会增大而且容易出错
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值