Java求解均值、中位数、众数的机试题未通过用例排查
现有实现的潜在失败场景定位
众数逻辑的核心缺陷
题目规则明确要求:当多个数值出现频率并列最高时,必须选择数值更小的作为众数。这类多众数场景是必测项——只要题目专门写了平局打破规则,就一定会覆盖{1,1,2,2}、{1,1,2,2,3,3}这类输入。
现有findMode方法的逻辑存在本质偏差:
- 仅当当前元素的出现频率严格大于已记录的最大频率时,才会更新众数结果;遇到同频的元素时,不会做任何处理。
- 最终返回的众数,是数组遍历过程中第一个达到最高频率的元素,而非同频下的最小值。
- 直接失败示例:输入数组
{2,2,1,1},按规则正确结果应该是1。但现有代码遍历到i=0位置的2时,就记录maxCount=2、maxValue=2,后续同频的1因为频率不超过2,永远不会触发更新,最终返回错误的2。 - 更极端的
{3,3,2,2,1,1}场景下,代码会直接返回3,和正确结果1差距极大。
其他隐藏的潜在失败点
整数溢出导致的均值错误
现有findMean方法用int类型存储数组总和:
- 题目允许数组长度最大为1000,如果数组元素为较大的整数值(比如单元素值为1e9,1000个元素的总和为1e12),会直接超出int的取值范围(约21亿),触发整数溢出,导致均值计算完全错误。
- 修正方式:将sum变量改为
long类型存储,再转为double做除法。
原地排序的副作用
现有findMedian方法直接对传入的原数组调用Arrays.sort(a):
- 这是原地修改操作,会打乱外部传入数组的原始顺序。如果测试用例的调用顺序是先计算众数、再计算中位数,后续的众数统计会基于已经被排序的数组进行——虽然数值本身的频率没有变化,但因为没有处理同频取最小的逻辑,依然会触发错误。
- 修正方式:排序前先复制数组副本,仅对副本做排序,不修改原数组。
众数逻辑的修正方案
两种可行实现路径:
- 统计频率时增加同频比较逻辑:当当前元素的频率等于已记录的最大频率时,比较当前元素和已记录的众数值,选择更小的更新结果。
- 提前对数组做升序排序后再遍历统计:因为升序数组本身是从小到大排列的,第一次达到最高频率的元素,就是所有同频值里最小的那个,不需要额外做大小比较。
参考修正后的众数代码:
public static int findMode(int n, int[] a) { int maxValue = 0, maxCount = 0; // 先对数组升序排序,保证遍历顺序为从小到大 Arrays.sort(a); for (int i = 0; i < a.length; i++) { int count = 0; for (int j = 0; j < a.length; j++) { if (a[j] == a[i]) count++; } // 升序遍历下,第一次达到最高频率的元素就是同频最小值 if (count > maxCount) { maxCount = count; maxValue = a[i]; } } return maxValue; }
未通过用例的原因匹配
- 众数逻辑未处理同频取最小,是最核心的失败原因,至少覆盖2-3个多众数类测试用例。
- 整数溢出场景,覆盖1个大数值输入的均值测试用例。
- 原地排序的副作用,可能与众数逻辑缺陷叠加,触发额外错误用例。
内容的提问来源于stack exchange,提问作者ASharma7
相关产品推荐
相关产品推荐

