📌  相关文章
📜  小范围值数组中每个元素的频率(1)

📅  最后修改于: 2023-12-03 15:39:21.198000             🧑  作者: Mango

小范围值数组中每个元素的频率

在计算机科学中,我们经常需要统计数组中每个元素出现的频率。本文将介绍两种常用的实现方法。其中,第一种方法适用于小范围值的数组,时间复杂度为O(n),第二种方法适用于大范围值的数组,时间复杂度为O(n log n)。

方法一:使用哈希表

我们可以使用哈希表来统计每个元素的频率。哈希表将每个元素与其出现的次数关联起来,我们可以一遍遍历数组来填充哈希表,然后再一遍遍历哈希表以获取结果。

使用哈希表的好处是它具有很快的查找和插入时间,并且可以很方便地实现。以下是一个C++的示例代码:

#include <iostream>
#include <unordered_map>
#include <vector>

using namespace std;

vector<int> freq(vector<int>& nums) {
    unordered_map<int, int> hash;
    vector<int> res;

    for (auto& num : nums) {
        hash[num]++;
    }

    for (auto& num : nums) {
        res.push_back(hash[num]);
    }

    return res;
}

int main() {
    vector<int> nums {1, 2, 2, 3, 3, 3};
    vector<int> res = freq(nums);

    for (auto& r : res) {
        cout << r << " ";
    }

    return 0;
}

上面的代码创建了一个freq函数,它使用了一个unordered_map哈希表来统计每个元素出现的次数,并返回一个包含每个元素频率的向量。我们可以看到,对于输入数组[1, 2, 2, 3, 3, 3],函数返回[1, 2, 2, 3, 3, 3],其中1出现了1次,2出现了2次,3出现了3次。

方法二:使用排序

如果数组中的元素值范围很大,我们可以使用类似桶排序的方法来统计每个元素的频率。首先,我们需要找到数组中最小和最大值,然后创建一个计数数组,并将所有元素插入该数组。最后,我们按升序遍历数组,每次访问计数数组中相应元素的值即可获得该元素的频率。

以下是一个C++的示例代码:

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

vector<int> freq(vector<int>& nums) {
    int min_num = *min_element(nums.begin(), nums.end());
    int max_num = *max_element(nums.begin(), nums.end());
    vector<int> counter(max_num - min_num + 1);

    for (auto& num : nums) {
        counter[num - min_num]++;
    }

    vector<int> res;

    for (auto& num : nums) {
        res.push_back(counter[num - min_num]);
    }

    return res;
}

int main() {
    vector<int> nums {1, 2, 2, 3, 3, 3};
    vector<int> res = freq(nums);

    for (auto& r : res) {
        cout << r << " ";
    }

    return 0;
}

上面的代码创建了一个freq函数,它使用了一个计数数组来统计每个元素出现的次数,并返回一个包含每个元素频率的向量。我们可以看到,对于输入数组[1, 2, 2, 3, 3, 3],函数返回[1, 2, 2, 3, 3, 3],其中1出现了1次,2出现了2次,3出现了3次。

不同于哈希表方法,排序方法需要先对数组进行排序,时间复杂度为O(n log n)。当输入数组的值范围较小时,使用哈希表方法可以获得更好的性能。但是,当输入数组的值范围较大时,排序方法往往更优秀,因为它所需要的内存更少。