leetcode 2090. K Radius Subarray Averages(半径为k的子数组的平均)

leetcode 2090. K Radius Subarray Averages(半径为k的子数组的平均)_第1张图片
k半径长度的子数组表示以数组下标 i 为中心,[i-k, i+k]范围内的子数组。
返回和数组nums一样长度的数组res,res[i] = [i-k, i+k]范围内的元素和 / 元素个数2k+1
如果 i-k 或者 i+k 超出了数组范围,res[i] = -1.

思路:

如果[i - k, i+k] 超出了数组范围, i处值为-1,
那么如果数组的长度 < 2k+1, 无论取哪个 i , [i-k, i+k]都会超出数组范围,这时返回全是-1的数组。

如果k = 0, 那么[i-k, i+k]就是i 本身,直接返回原数组nums.

如果i-k超出数组范围,也就是i-k < 0, 所以 i < k处全部填上-1.
同理 i + k > n-1时超出数组右边范围,所以 i > n-k-1处全部填上-1.
现在只需要看 i = k ~ n-k 范围内的。

涉及到一个范围内的数组求和,用到积分数组.
那么res[i] = (acc[i+k] - acc[i-k-1]) / (2k+1)

注意nums[i]最大到105, 数组长度最大达到105, 所以积分数组acc用long型防止溢出。

public int[] getAverages(int[] nums, int k) {
    int n = nums.length;
    if(k == 0) return nums;
    int[] res = new int[n];
    if(n < (2*k + 1)) {
        Arrays.fill(res, -1);
        return res;
    }

    long[] acc = new long[n+1];
    for(int i = 0; i < n; i++) {
        acc[i+1] = acc[i] + nums[i];
    }

    Arrays.fill(res, 0, k, -1);
    Arrays.fill(res, n-k, n, -1);
    int divide = 2*k+1;

    for(int i = k; i < n-k; i++) {
         res[i] = (int)((acc[i+k+1]-acc[i-k])/divide);
    }
    return res;
}

你可能感兴趣的:(leetcode,leetcode,算法)