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

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

登录—专业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

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

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

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

#include <iostream>
#include <unordered_set>

int main() {
    std::unordered_set<int> mySet;

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

    // 使用范围构造函数插入元素
    std::unordered_set<int> 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 <iostream>
#include <unordered_set>
#include <vector>

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

    for (int i=0;i<nums.size();i++) {
        if (seen.find(nums[i]) == seen.end()) {
            result.push_back(nums[i]);
            seen.insert(nums[i]);
        }
    }

    for (int num : result) {
        std::cout << num << " ";
    }
    std::cout << std::endl;
}

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

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

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

        removeDuplicates(nums);
    }

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

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

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

        unordered_set<int> uniqueNums;
        for (int i=0;i<nums.size();i++) {
            uniqueNums.insert(nums[i]);
        }

        for (int i=0;i<nums.size();i++) {
            if (uniqueNums.count(nums[i]) > 0) {
                cout << nums[i] << " ";
                uniqueNums.erase(nums[i]);
            }
        }
        cout << endl;
    }

    return 0;
}

​

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

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

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

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

本题平衡树解法:

#include <iostream>
#include <set>
#include <vector>

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

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

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

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

    return 0;
}

  • 6
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值