📅  最后修改于: 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)。当输入数组的值范围较小时,使用哈希表方法可以获得更好的性能。但是,当输入数组的值范围较大时,排序方法往往更优秀,因为它所需要的内存更少。