【PAT甲级 - C++题解】1097 Deduplication on a Linked List

简介: 【PAT甲级 - C++题解】1097 Deduplication on a Linked List

1097 Deduplication on a Linked List


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


题意

第一行给定链表起始结点的地址 h 以及结点总数量 n 。


现在要求我们将该链表中数据重复的结点和数据不重复的结点拆分成两个链表并输出,此题对于正数和负数都相同的数据都算重复数据即数据绝对值不能重复。


思路

具体思路如下:


1.先将结点读入到数组当中,方便后续调用。

2.从起始地址开始往后遍历该链表,并用一个数组 st 来判断是否出现重复的数据,如果该数据是第一次出现,则加入数组 a 中,反之加入数组 b 中。

3.分别输出两个链表,注意地址需要是 5 位数字。


代码

#include<bits/stdc++.h>
using namespace std;
const int N = 100010;
int n, h;
int e[N], ne[N];
bool st[N];
int main()
{
    //输入每个结点的信息
    cin >> h >> n;
    for (int i = 0; i < n; i++)
    {
        int address, data, next;
        scanf("%d%d%d", &address, &data, &next);
        e[address] = data, ne[address] = next;
    }
    //将链表中不重数据和重复数据拆分成两个链表
    vector<int> a, b;
    for (int i = h; i != -1; i = ne[i])
    {
        int data = abs(e[i]);
        if (st[data])    b.push_back(i);
        else
        {
            a.push_back(i);
            st[data] = true;
        }
    }
    //输出不重数据链表
    for (int i = 0; i < a.size(); i++)
    {
        printf("%05d %d ", a[i], e[a[i]]);
        if (i + 1 == a.size())   puts("-1");
        else printf("%05d\n", a[i + 1]);
    }
    //输出重复数据链表
    for (int i = 0; i < b.size(); i++)
    {
        printf("%05d %d ", b[i], e[b[i]]);
        if (i + 1 == b.size())   puts("-1");
        else printf("%05d\n", b[i + 1]);
    }
    return 0;
}
目录
相关文章
|
1月前
|
存储 缓存 C语言
【C++】list介绍以及模拟实现(超级详细)
【C++】list介绍以及模拟实现(超级详细)
48 5
|
1月前
|
存储 缓存 算法
【C++】list的模拟实现
【C++】list的模拟实现
|
1月前
|
存储 C++ 容器
【C++】list的认识与使用
【C++】list的认识与使用
|
2月前
|
存储 Java C++
【c++】list详细讲解
【c++】list详细讲解
33 5
|
2月前
|
Java C++ Python
【c++】list 模拟
【c++】list 模拟
20 1
|
2月前
|
存储 编译器 C语言
【C++】list模拟实现
本文档介绍了C++ STL中`list`容器的模拟实现,包括`ListNode`节点类、迭代器类和`list`类的详细设计。`ListNode`模板类存储数据并维护前后指针;`ListIterator`是一个复杂的模板类,提供解引用、自增/自减以及比较操作。`list`类包含了链表的各种操作,如插入、删除、访问元素等,并使用迭代器作为访问接口。实现中,迭代器不再是简单的指针,而是拥有完整功能的对象。此外,文档还提到了迭代器的实现对C++语法的特殊处理,使得`it-&gt;_val`的写法成为可能。文章通过分步骤展示`list`的各个组件的实现,帮助读者深入理解STL容器的内部工作原理。
|
2月前
|
算法 搜索推荐 C++
【C++】list的使用(下)
`C++` 中 `std::list` 的 `merge()`、`sort()` 和 `reverse()` 操作: - `merge(x)` 和 `merge(x, comp)`: 合并两个已排序的`list`,将`x`的元素按顺序插入当前`list`,`x`清空。比较可自定义。 - `sort()` 和 `sort(comp)`: 对`list`元素排序,保持等价元素相对顺序。内置排序基于稳定排序算法,速度较慢。 -reverse(): 反转`list`中元素的顺序。 这些操作不涉及元素构造/销毁,直接移动元素。注意,`sort()`不适合`std::list`,因链表结构不利于快速排序
|
2月前
|
C++ 容器
【C++】list的使用(下)
这篇博客探讨了C++ STL中`list`容器的几个关键操作,包括`splice()`、`remove()`、`remove_if()`和`unique()`。`splice()`允许高效地合并或移动`list`中的元素,无需构造或销毁。`remove()`根据值删除元素,而`remove_if()`则基于谓词移除元素。`unique()`则去除连续重复的元素,可选地使用自定义比较函数。每个操作都附带了代码示例以说明其用法。
|
2月前
|
编译器 C++ 容器
【C++】list的使用(上)
迭代器在STL中统一了访问接口,如`list`的`begin()`和`end()`。示例展示了如何使用正向和反向迭代器遍历`list`。注意`list`的迭代器不支持加减操作,只能用`++`和`--`。容器的`empty()`和`size()`用于检查状态和获取元素数。`front()`和`back()`访问首尾元素,`assign()`重载函数用于替换内容,`push_*/pop_*`管理两端元素,`insert()`插入元素,`erase()`删除元素,`resize()`调整大小,`clear()`清空容器。这些接口与`vector`和`string`类似,方便使用。
|
2月前
|
存储 编译器 C语言
【C++】list的使用(上)
**C++ STL的list是一个基于双向循环链表的容器,支持常数时间内插入和删除,但不支持随机访问。默认构造函数、填充构造、迭代器范围构造和拷贝构造提供多种初始化方式。析构函数自动释放内存,赋值运算符重载用于内容替换。示例代码展示了构造和赋值操作。**