牛客——不重复数字(哈希表、平衡树)

今天的第二题。下面这道题呢有两种解法,一种基于哈希表,一种基于平衡树。

登录—专业IT笔试面试备考平台_牛客网
 

题目描述

给出N个数,要求把其中重复的去掉,只保留第一次出现的数。 

例如,给出的数为1 2 18 3 3 19 2 3 6 5 4,其中2和3有重复,去除后的结果为1 2 18 3 19 6 5 4。  

输入描述:

输入第一行为正整数T,表示有T组数据。
接下来每组数据包括两行,第一行为正整数N,表示有N个数。
第二行为要去重的N个正整数。

输出描述:

对于每组数据,输出一行,为去重后剩下的数字,数字之间用一个空格隔开。

示例1

输入

2
11
1 2 18 3 3 19 2 3 6 5 4
6
1 2 3 4 5 6

输出

1 2 18 3 19 6 5 4
1 2 3 4 5 6

牛客——不重复数字(哈希表、平衡树)_第1张图片

        这道题使用哈希表(Hash Table)算法来实现去重操作。具体而言,我们使用了unordered_set来存储已经出现过的数,利用该数据结构的特性,可以快速判断一个数是否已经存在于集合中。通过遍历输入的数列,将每个数添加到哈希表中,并判断是否已经存在,从而实现去重操作。

        在C++中,unordered_set是哈希表的实现之一,而unordered_map则是实现哈希表的关联容器。这两个容器都是C++标准库提供的,用于存储无序的键值对。在本题中,我们只需要记录数的出现情况,因此选择使用unordered_set来实现哈希表。

下面是向 unordered_set 插入和删除元素的示例代码:

#include 
#include 

int main() {
    std::unordered_set mySet;

    // 插入元素
    mySet.insert(10);
    mySet.insert(20);
    mySet.insert(30);

    // 使用范围构造函数插入元素
    std::unordered_set otherSet = {40, 50, 60};
    mySet.insert(otherSet.begin(), otherSet.end());

    // 删除元素
    mySet.erase(20);  // 删除值为 20 的元素

    // 遍历元素
    for (int num : mySet) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}

本题哈希表解法代码为:

#include 
#include 
#include 

void removeDuplicates(const std::vector& nums) {
    std::unordered_set seen;
    std::vector result;

    for (int i=0;i> t;

    while (t--) {
        int n;
        std::cin >> n;

        std::vector nums(n);
        for (int i = 0; i < n; i++) {
            std::cin >> nums[i];
        }

        removeDuplicates(nums);
    }

    return 0;
}
​
#include 
#include 
#include 
#include 
using namespace std;
int main() {
    int T;
    cin >> T;

    while (T--) {
        int N;
        cin >> N;

        vector nums(N);
        for (int i = 0; i < N; i++) {
            cin >> nums[i];
        }

        unordered_set uniqueNums;
        for (int i=0;i 0) {
                cout << nums[i] << " ";
                uniqueNums.erase(nums[i]);
            }
        }
        cout << endl;
    }

    return 0;
}

​

平衡树和哈希表是两种不同的数据结构,在解决去重问题时可以使用它们来实现相同的功能,但它们的实现细节和性能特点有所不同。

平衡树(如红黑树、AVL树)是一种自平衡的二叉搜索树,它保持树的高度平衡,可以在O(log N)的时间复杂度内进行插入、查找和删除操作。平衡树的主要优点是可以保持元素的有序性,且插入和删除操作相对较快。因此,使用平衡树来解决去重问题时,可以保持去重后的元素有序。

哈希表是一种基于哈希函数的数据结构,通过将关键字映射到哈希表中的位置来进行查找和插入操作。哈希表的主要优点是查找和插入操作的平均时间复杂度为O(1),即常数时间。哈希表的缺点是无法保持元素的有序性,且在存在哈希冲突时,可能需要处理冲突的情况。

对于去重问题,平衡树和哈希表的做法可以达到相同的去重效果,但它们的实现方式和性能特点有所不同。平衡树适用于需要保持元素有序性的场景,而哈希表适用于查找和插入操作频繁的场景,并且不需要保持有序性。

本题平衡树解法:

#include 
#include 
#include 

int main() {
    int T;
    std::cin >> T;

    while (T--) {
        int N;
        std::cin >> N;

        std::vector nums(N);
        for (int i = 0; i < N; i++) {
            std::cin >> nums[i];
        }

        std::set uniqueNums;
        for (int num : nums) {
            if (uniqueNums.find(num) == uniqueNums.end()) {
                uniqueNums.insert(num);
                std::cout << num << " ";
            }
        }
        std::cout << std::endl;
    }

    return 0;
}

你可能感兴趣的:(散列表,数据结构)