Featured image of post 2090. 半径为 k 的子数组平均值

2090. 半径为 k 的子数组平均值

题目描述

给你一个下标从 0 开始的数组 nums ,数组中有 n 个整数,另给你一个整数 k 。

半径为 k 的子数组平均值 是指:nums 中一个以下标 i 为 中心 且 半径 为 k 的子数组中所有元素的平均值,即下标在 i - k 和 i + k 范围(含 i - k 和 i + k)内所有元素的平均值。如果在下标 i 前或后不足 k 个元素,那么 半径为 k 的子数组平均值 是 -1 。

构建并返回一个长度为 n 的数组 avgs ,其中 avgs[i] 是以下标 i 为中心的子数组的 半径为 k 的子数组平均值 。

x 个元素的 平均值 是 x 个元素相加之和除以 x ,此时使用截断式 整数除法 ,即需要去掉结果的小数部分。

例如,四个元素 2、3、1 和 5 的平均值是 (2 + 3 + 1 + 5) / 4 = 11 / 4 = 2.75,截断后得到 2 。

2090. 半径为 k 的子数组平均值

2090. K Radius Subarray Averages

解法

  • 滑动窗口:时间复杂度 O(n),空间复杂度 O(1)

滑动窗口

需要注意的是,在计算平均值时,需要使用 long 类型,否则会溢出。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
public int[] getAverages(int[] nums, int k) {
    int left = 0, right = 0;
    long sum = 0L;  // 子数组和  可能超出 int 范围 所以用 long 类型
    int[] result = new int[nums.length];
    Arrays.fill(result, -1);
    while (right < nums.length) {
        sum += nums[right];
        right++;    // 右指针右移
        while (right - left >= 2 * k + 1) {  // 子数组长度为 2k+1 即右指针 - 左指针 = 2k 进入子数组计算
            result[right - k - 1] = (int) (sum / (2L * k + 1));  // 计算子数组最大平均数 即子数组和 / 子数组长度
            sum -= nums[left];
            left++;    // 左指针右移
        }
    }
    return result;
}
使用 Hugo 构建
主题 StackJimmy 设计