最小平均差
难度:
标签:
题目描述
代码结果
运行时间: 135 ms, 内存: 25.0 MB
/*
* 思路:
* 1. 使用流计算 nums 的总和。
* 2. 通过流来遍历每个下标,计算前 i + 1 个元素和后 n - i - 1 个元素的平均值,然后计算绝对差。
* 3. 通过流操作找到最小绝对差的下标。
*/
import java.util.stream.IntStream;
public int minimumAverageDifference(int[] nums) {
int n = nums.length;
long totalSum = IntStream.of(nums).asLongStream().sum();
long[] preSum = new long[n];
preSum[0] = nums[0];
for (int i = 1; i < n; i++) {
preSum[i] = preSum[i - 1] + nums[i];
}
return IntStream.range(0, n).reduce((i, j) -> {
long frontAvg = preSum[i] / (i + 1);
long backAvg = (n - i - 1 == 0) ? 0 : (totalSum - preSum[i]) / (n - i - 1);
long diff1 = Math.abs(frontAvg - backAvg);
long frontAvg2 = preSum[j] / (j + 1);
long backAvg2 = (n - j - 1 == 0) ? 0 : (totalSum - preSum[j]) / (n - j - 1);
long diff2 = Math.abs(frontAvg2 - backAvg2);
return diff1 <= diff2 ? i : j;
}).orElse(0);
}
解释
方法:
此题解采用前缀和和后缀和的概念来计算每个下标处的平均差。使用两个变量pre和suf分别存储从数组开始到当前索引的元素之和(前缀和),以及当前索引后所有元素的和(后缀和)。通过逐步更新这两个和,我们可以有效地计算任意位置的平均差。循环遍历每个元素,更新前缀和与后缀和,并计算当前下标的平均差。如果计算得到的平均差小于之前的最小平均差,则更新最小平均差和对应的下标。最后,单独处理数组最后一个元素的情况,因为其后没有元素,后缀和为0。
时间复杂度:
O(n)
空间复杂度:
O(1)
代码细节讲解
🦆
为什么在计算平均差时需要使用整数除法而不是常规的浮点数除法?
▷🦆
在计算平均差的过程中,当数组长度n为1时,算法如何处理,是否会存在除以0的错误?
▷🦆
题解中提到的‘单独处理最后一个元素的情况’是基于什么考虑?最后一个元素的后缀和不是应该为0吗?
▷🦆
当数组中所有元素相等时,这种方法是否仍然有效?结果是否始终为数组的第一个或最后一个索引?
▷