用std::map或unordered_map统计频次再找最大值是求众数的标准做法;元素范围有限时可用数组优化;需处理空输入、多众数、浮点数精度等边界情况。

用 std::map 统计频次是最直接稳妥的做法
众数本质是频次最高的元素,c++ 没有内置“求众数”函数,必须手动统计。用 std::map 或 std::unordered_map 记录每个值出现的次数,再遍历找最大频次对应的键即可。
注意:如果多个数并列最高频次(如 {1,1,2,2,3}),默认返回第一个遇到的众数;若需全部众数,得额外收集。
int findMode(const std::vector& nums) { std::unordered_map count; for (int x : nums) count[x]++; int mode = nums[0], maxCnt = 0; for (const auto& p : count) { if (p.second youjiankuohaophpcn maxCnt) { maxCnt = p.second; mode = p.first; } } return mode;
}
数组元素范围有限时,用数组代替哈希表更高效
当已知元素值在较小固定范围内(比如 0 ~ 99 或 -1000 ~ 1000),直接用原生数组做计数桶,避免哈希开销,且支持负数偏移处理。
立即学习“C++免费学习笔记(深入)”;
- 若最小值为
min_val,申请大小为max_val - min_val + 1的数组 - 访问时用
count[x - min_val],防止越界 - 时间复杂度仍是 O(n),但常数更小,无哈希碰撞风险
处理多众数或空输入等边界情况要主动判断
实际使用中容易忽略这些点:
-
nums.empty()时未检查,直接访问nums[0]导致未定义行为 - 所有元素频次相同(如
{1,2,3}),按题意可能需返回任意一个,或报错,得看需求 - 众数不唯一但只要求一个结果时,
std::map遍历顺序不保证,而std::unordered_map更不可控——若需稳定返回最小/最大众数,得在比较逻辑里加约束
用 std::max_element 配合 Lambda 可简化查找过程
统计完频次后,不必手写循环找最大值,用 STL 算法更简洁安全:
auto it = std::max_element(count.begin(), count.end(), [](const auto& a, const auto& b) { return a.second < b.second; }); return it->first;
但注意:std::max_element 对空容器会 UB,务必先判空;另外,它只返回第一个最大值迭代器,和手写循环行为一致。
真正容易被忽略的是:众数定义依赖于“至少出现一次”,但如果你的输入含大量重复浮点数或自定义类型,== 行为或哈希实现是否合理,就得另作校验了。