力扣刷题笔记 → 5939. 半径为 k 的子数组平均值

这是我参与11月更文挑战的第28天,活动详情查看:2021最后一次更文挑战

题目

给你一个下标从 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 ,此时使用截断式 整数除法 ,即需要去掉结果的小数部分。

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

示例

image.png

输入: nums = [7,4,3,9,1,8,5,2,6], k = 3
输出: [-1,-1,-1,5,4,4,-1,-1,-1]
解释:
- avg[0]、avg[1] 和 avg[2] 是 -1 ,因为在这几个下标前的元素数量都不足 k 个。
- 中心为下标 3 且半径为 3 的子数组的元素总和是:7 + 4 + 3 + 9 + 1 + 8 + 5 = 37 。
  使用截断式 整数除法,avg[3] = 37 / 7 = 5 。
- 中心为下标 4 的子数组,avg[4] = (4 + 3 + 9 + 1 + 8 + 5 + 2) / 7 = 4 。
- 中心为下标 5 的子数组,avg[5] = (3 + 9 + 1 + 8 + 5 + 2 + 6) / 7 = 4 。
- avg[6]、avg[7] 和 avg[8] 是 -1 ,因为在这几个下标后的元素数量都不足 k 个。
复制代码
输入: nums = [100000], k = 0
输出: [100000]
解释:
- 中心为下标 0 且半径 0 的子数组的元素总和是:100000 。
  avg[0] = 100000 / 1 = 100000 。
复制代码
输入: nums = [8], k = 100000
输出: [-1]
解释:
- avg[0] 是 -1 ,因为在下标 0 前后的元素数量均不足 k 。
复制代码

提示

  • n == nums.length
  • 1 <= n <= 10^5
  • 0 <= nums[i], k <= 10^5

解题思路

滑动窗口

要计算一段长度为k的子数组平均值,滑动窗口无疑是一个很好的方式,固定窗口长度k * 2 + 1,统计出区间总和,再求得平均值avg之后填入到中心位置对应索引处即可。然后向右滑动,增加右边元素,减去左边元素,继续重复前面的求和取平均值步骤。

class Solution {
    public int[] getAverages(int[] nums, int k) {
        // 边界判断
        if(k == 0){
            return nums;
        }
        int n = nums.length;
        int[] ans = new int[n];
        Arrays.fill(ans, -1);
        if(n < k * 2 + 1){
            return ans;
        }
        
        // 由于n的取值范围比较大,这里需要采用long类型来统计区间和
        long sum = 0;
        int left = 0, right = 0;
        // 初始化窗口区间和,这里要预留最右边一位数
        while(right - left < k * 2){
            sum += nums[right++];
        }
        
        while(right < n){
            // 加上最右边的元素
            sum += nums[right++];
            // 求平均值,将其赋值给中间点
            ans[left + k] = (int)(sum / (k * 2 + 1));
            // 减去最左边的元素
            sum -= nums[left++];
        }
        
        return ans;
    }
}
复制代码

 复杂度分析

  •   时间复杂度: O ( N ) O(N)
  •   空间复杂度: O ( N ) O(N)

最后

文章有写的不好的地方,请大佬们不吝赐教,错误是最能让人成长的,愿我与大佬间的距离逐渐缩短!

如果觉得文章对你有帮助,请 点赞、收藏、关注、评论 一键四连支持,你的支持就是我创作最大的动力!!!

题目出处:

猜你喜欢

转载自juejin.im/post/7035615596112773156