K Radius Subarray Averages

Updated on 04 June, 2025
K Radius Subarray Averages header image

Problem Statement

Given a 0-indexed array of integers named nums with size n, and another integer k, you need to compute what's called the "k-radius average" for each element in the array focused around its position. The k-radius average for an element at index i is the average of all numbers in the array from the indices i - k to i + k inclusive. If the index i doesn't have k elements before or after it, then the k-radius average will be -1 indicating an incomplete radius.

The average should be calculated using integer division, which discards any fractional parts. For instance, the integer division of 11 by 4 results in 2 since 11/4 rounds down to 2. Your task is to create an output array, avgs, where each element avgs[i] represents the k-radius average of nums centered at index i.

Examples

Example 1

Input:

nums = [7,4,3,9,1,8,5,2,6], k = 3

Output:

[-1,-1,-1,5,4,4,-1,-1,-1]

Explanation:

- avg[0], avg[1], and avg[2] are -1 because there are less than k elements before each index.
- avg[3] = (7 + 4 + 3 + 9 + 1 + 8 + 5) / 7 = 5
- avg[4] = (4 + 3 + 9 + 1 + 8 + 5 + 2) / 7 = 4
- avg[5] = (3 + 9 + 1 + 8 + 5 + 2 + 6) / 7 = 4
- avg[6], avg[7], and avg[8] are -1 because there are less than k elements after each index.

Example 2

Input:

nums = [100000], k = 0

Output:

[100000]

Explanation:

- Only one element, so its radius-0 average is itself.

Example 3

Input:

nums = [8], k = 100000

Output:

[-1]

Explanation:

- Not enough elements to form a radius of size 100000 on either side.

Constraints

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

Approach and Intuition

  1. Initialize a result array avgs filled with -1s. This accounts for all positions where a full k-radius cannot be formed.

  2. Use a sliding window of size 2k + 1 to efficiently compute the sum for each valid center position.

  3. Start by computing the initial window sum from index 0 to 2k, if possible.

  4. For each index i from k to n - k - 1, compute:

    • The average as window_sum // (2k + 1) and assign it to avgs[i].
    • Update the window sum by subtracting the element leaving the window and adding the new one entering.
  5. Return the completed avgs array. This approach ensures O(n) time complexity by avoiding repeated summing.

Solutions

  • C++
  • Java
  • JavaScript
  • Python
cpp
class Solution {
public:
    vector<int> calculateAverages(vector<int>& elements, int k) {
        if (k == 0) {
            return elements;
        }

        int totalCount = 2 * k + 1;
        int size = elements.size();
        vector<int> result(size, -1);

        if (totalCount > size) {
            return result;
        }

        long long sum = 0;
        for (int i = 0; i < totalCount; ++i) {
            sum += elements[i];
        }
        result[k] = sum / totalCount;

        for (int i = totalCount; i < size; ++i) {
            sum = sum - elements[i - totalCount] + elements[i];
            result[i - k] = sum / totalCount;
        }

        return result;
    }
};

This solution pertains to calculating the average of subarrays given a radius, k, implemented in C++. The code encompasses a function calculateAverages which takes a vector of integers (elements) and an integer k as inputs. The logic flows as follows:

  • Check if the radius k equals zero. If it does, return the original elements since no averaging is required.
  • Define totalCount as 2 * k + 1, which is the size of each subarray to average.
  • Initialize a result vector of size equal to elements, filled with -1. This is because some positions in the output may remain unaffected when totalCount exceeds the available elements to form a full subarray.
  • If totalCount exceeds the total number of elements (size), immediately return the result, as no valid subarrays could be formed.
  • Compute the initial sum of the first totalCount elements and store the average in the result at the position k.
  • Slide the window across the elements vector by moving one element right at a time. Update the sum by subtracting the element that left the window and adding the new element entering the window. Store each computed average at the corresponding position in the result vector.
  • Return the modified result vector containing the subarray averages and untouched positions as -1 if a subarray could not be formed.

This vector operation ensures a more efficient subarray averaging under the constraints given, rather than computing each subarray's average from scratch, thereby optimizing the algorithm overall.

java
class Solution {
    public int[] calculateAverages(int[] arr, int k) {
        if (k == 0) {
            return arr;
        }

        int len = 2 * k + 1;
        int size = arr.length;
        int[] result = new int[size];
        Arrays.fill(result, -1);

        if (len > size) {
            return result;
        }

        long sum = 0;
        for (int j = 0; j < len; ++j) {
            sum += arr[j];
        }
        result[k] = (int) (sum / len);

        for (int j = len; j < size; ++j) {
            sum = sum - arr[j - len] + arr[j];
            result[j - k] = (int) (sum / len);
        }

        return result;
    }
}

In this solution, the objective is to calculate the average of every contiguous subarray of length 2k + 1 for an integer array, where k is a non-negative integer. If k is 0, the original array is returned as each element averages to itself.

  • Start by checking if k is 0, returning the array immediately if true.
  • Initialize variables for the array length (len, calculated as 2 * k + 1), the input size, and the result array filled initially with -1.
  • If len exceeds the size of the input array, immediately return the result array filled with -1, as no valid average can be computed.
  • Begin by calculating the sum of the first len elements of the array.
  • Store the first computed average in the result array at position k.
  • Loop through the array, adjusting the sum by subtracting the element that moves out of the sliding window and adding the new element coming into the window.
  • Calculate and store each resulting average at the appropriate index (j - k) in the result array.
  • Return the result array, which now contains the averages or -1 for positions where the average could not be computed due to the window size.

This approach uses a sliding window technique to efficiently compute running averages without recalculating the sum for overlapping parts of the array.

js
var calculateAverages = function(numbers, scope) {
    // Special case for zero radius.
    if (scope === 0) return numbers;

    const radius = 2 * scope + 1;
    const totalCnt = numbers.length;
    const windowAvg = new Array(totalCnt).fill(-1);

    // If window is larger than available numbers, return.
    if (radius > totalCnt) return windowAvg;

    // Calculating the first window sum.
    let sum = 0;
    for (let j = 0; j < radius; ++j) {
        sum += numbers[j];
    }
    windowAvg[scope] = Math.floor(sum / radius);

    // Compute averages for subsequent windows.
    for (let j = radius; j < totalCnt; ++j) {
        sum = sum - numbers[j - radius] + numbers[j];
        windowAvg[j - scope] = Math.floor(sum / radius);
    }

    return windowAvg;
};

The function calculateAverages in JavaScript computes the average of every subarray of given radius k from a list of numbers.

  • Initialize a function called calculateAverages that takes numbers (an array of integers) and scope (the radius k) as arguments.

  • Handle edge cases:

    • If scope equals 0, directly return the original numbers array as no averaging is needed.
    • Calculate the required window size as 2 * scope + 1.
    • Initialize an array windowAvg filled with -1, which will hold the computed averages or remain -1 if the window cannot fit at a specific position.
    • If the computed radius exceeds the length of the numbers array, immediately return windowAvg filled with -1.
  • Compute the average for the initial window:

    • Start with sum set to 0 and accumulate the numbers in the first window.
    • Compute the average for this window and store it at the correct index in windowAvg.
  • Calculate averages for the subsequent windows using a sliding window approach:

    • Iterate through the numbers array starting from the index radius to the end of numbers.
    • For each index j, modify sum by removing the number that is leaving the window and adding the number that is entering.
    • Compute and store the average for the current window.
  • Finally, return windowAvg which contains all the computed averages or -1 for indices where a full window couldn't be formed.

python
class Solution:
    def calculateAverages(self, data: List[int], width: int) -> List[int]:
        result = [-1] * len(data)
        # Direct assignment of elements when k=0 for each element's own average.
        if width == 0:
            return data

        span = 2 * width + 1
        total_length = len(data)
        
        # Condition where sliding window is bigger than the list.
        if span > total_length:
            return result

        # Calculate the sum for the initial window.
        current_sum = sum(data[:span])
        result[width] = current_sum // span

        # Slide the window across the list.
        for index in range(span, total_length):
            current_sum = current_sum - data[index - span] + data[index]
            result[index - width] = current_sum // span

        return result

Solution Summary:

The provided Python 3 code addresses the problem of computing averages from subarrays of a given radius within an array. The class Solution contains a method calculateAverages which takes two parameters: data, which is a list of integers representing the data points, and width, an integer representing the radius around each element to calculate the average. Here’s a breakdown of the method’s implementation:

  • The method initializes the result list with all elements set as -1, which will be the output list for storing the averages.
  • An early return provides the original data list if the specified width is zero, since the average of each data point with only itself is the data point.
  • The span of considered elements for each center data point is calculated as 2 * width + 1. If this span exceeds the total number of elements in the original list, the method immediately returns the result list of -1s.
  • Begin by calculating the sum of elements in the initial window spanning the first span elements.
  • This sum is then used to derive the average for the position at zero-indexed position width.
  • As the window slides through the list, the sum is updated by removing the element that is left behind and adding the new element entering the window.
  • This updated sum is then used to calculate the average for the new center position.
  • The method finally returns the list of calculated averages or -1 for positions where an average couldn't be derived due to the radius extending beyond the bounds of the list.

The key operations involve maintaining an effective sliding window to compute sums dynamically and updating this window efficiently to derive consecutive averages. The approach ensures optimal use of computational resources by avoiding recalculation of the sum for overlapping window parts.

Comments

No comments yet.