
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
Initialize a result array
avgs
filled with-1
s. This accounts for all positions where a full k-radius cannot be formed.Use a sliding window of size
2k + 1
to efficiently compute the sum for each valid center position.Start by computing the initial window sum from index
0
to2k
, if possible.For each index
i
fromk
ton - k - 1
, compute:- The average as
window_sum // (2k + 1)
and assign it toavgs[i]
. - Update the window sum by subtracting the element leaving the window and adding the new one entering.
- The average as
Return the completed
avgs
array. This approach ensuresO(n)
time complexity by avoiding repeated summing.
Solutions
- C++
- Java
- JavaScript
- Python
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 originalelements
since no averaging is required. - Define
totalCount
as2 * 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 whentotalCount
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 positionk
. - 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.
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 as2 * k + 1
), the input size, and the result array filled initially with-1
. - If
len
exceeds thesize
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.
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 takesnumbers
(an array of integers) andscope
(the radiusk
) as arguments.Handle edge cases:
- If
scope
equals0
, 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
.
- If
Compute the average for the initial window:
- Start with
sum
set to0
and accumulate the numbers in the first window. - Compute the average for this window and store it at the correct index in
windowAvg
.
- Start with
Calculate averages for the subsequent windows using a sliding window approach:
- Iterate through the numbers array starting from the index
radius
to the end ofnumbers
. - For each index
j
, modifysum
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.
- Iterate through the numbers array starting from the index
Finally, return
windowAvg
which contains all the computed averages or-1
for indices where a full window couldn't be formed.
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.
No comments yet.