大样本统计
难度:
标签:
题目描述
代码结果
运行时间: 23 ms, 内存: 16.1 MB
/*
* 思路:
* 1. 使用IntStream来遍历count数组。
* 2. 通过filter和summaryStatistics找到最小值、最大值和求和。
* 3. 计算总和sum和总数totalCount,得出均值。
* 4. 使用IntStream和Collectors来计算中位数和众数。
*/
import java.util.stream.IntStream;
import java.util.stream.Collectors;
import java.util.*;
public class Solution {
public double[] sampleStats(int[] count) {
int min = IntStream.range(0, count.length).filter(i -> count[i] > 0).findFirst().orElse(-1);
int max = IntStream.range(0, count.length).filter(i -> count[i] > 0).reduce((a, b) -> b).orElse(-1);
long totalCount = IntStream.of(count).sum();
double mean = IntStream.range(0, count.length).mapToDouble(i -> i * count[i]).sum() / totalCount;
int mode = IntStream.range(0, count.length).boxed().max(Comparator.comparingInt(i -> count[i])).orElse(-1);
long mid = (totalCount + 1) / 2;
long currCount = 0;
double median = 0;
List<Integer> list = IntStream.range(0, count.length).boxed().collect(Collectors.toList());
for (int i : list) {
currCount += count[i];
if (currCount >= mid) {
if (totalCount % 2 == 1) {
median = i;
} else {
if (currCount == mid) {
for (int j = i + 1; j < count.length; j++) {
if (count[j] > 0) {
median = (i + j) / 2.0;
break;
}
}
} else {
median = i;
}
}
break;
}
}
return new double[]{min, max, mean, median, mode};
}
}
解释
方法:
题解通过一次遍历数组 count,计算最小值、最大值、平均值、中位数和众数。最小值和最大值通过检查每个数字的计数是否大于零并更新最小或最大索引来得到。平均值通过累加所有数字乘以其出现次数再除以总数计算。中位数通过累积出现的次数直到达到或超过总数的一半来确定。如果总元素数是奇数,中位数是累计到的那个数;如果是偶数,则取累积到的两个数的平均值。众数是出现次数最多的数字。
时间复杂度:
O(256) => O(1)
空间复杂度:
O(1)
代码细节讲解
🦆
如何从count数组中准确地确定最小值和最大值,尤其是在存在大量0计数的情况下?
▷🦆
在计算平均值mean时,是否需要考虑整数溢出的问题,特别是当样本大小非常大的情况下?
▷🦆
计算中位数时,如何处理累积频率恰好等于n/2的情况,特别是在元素个数为偶数时?
▷🦆
为何在找众数时只记录了一个最大频率的数字,而没有考虑可能存在两个或更多具有相同最高频率的数字?
▷