Given an integer array nums consisting of n elements, and an integer k.
Find a contiguous subarray whose length is greater than or equal to k that has the maximum average value, and return this value. Any answer with a calculation error less than 10-5 will be accepted.
Example 1:
Input: nums = [1,12,-5,-6,50,3], k = 4 Output: 12.75000 Explanation: When length is 5, maximum average value is 10.8. When length is 6, maximum average value is 9.16667. Thus answer is 12.75000.
Example 2:
Input: nums = [5], k = 1 Output: 5.00000
Constraints:
n == nums.length1 <= k <= n <= 105-104 <= nums[i] <= 104When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force approach for finding the maximum average involves checking every possible group of numbers. We calculate the average for each group we try. Ultimately, we compare all of the averages and return the largest one we found.
Here's how the algorithm would work step-by-step:
def find_max_average_brute_force(numbers, minimum_group_size):
maximum_average = float('-inf')
# Iterate through all possible group sizes
for current_group_size in range(minimum_group_size, len(numbers) + 1):
# Iterate through all possible starting positions for the current group size
for start_index in range(len(numbers) - current_group_size + 1):
current_sum = 0
# Calculate the sum of the current group
for index in range(start_index, start_index + current_group_size):
current_sum += numbers[index]
current_average = current_sum / current_group_size
# Keep track of the highest average
if current_average > maximum_average:
maximum_average = current_average
return maximum_averageThe goal is to find the segment with the highest average. Instead of checking every possible segment, we'll use a clever technique to efficiently narrow down our search by guessing the average and checking if it's possible to find a segment with at least that average.
Here's how the algorithm would work step-by-step:
def find_maximum_average(nums, minimum_length):
lower_bound = min(nums)
upper_bound = max(nums)
# Binary search to find the maximum average.
while upper_bound - lower_bound > 1e-5:
mid_point = (lower_bound + upper_bound) / 2
if check_average(nums, minimum_length, mid_point):
lower_bound = mid_point
else:
upper_bound = mid_point
return lower_bound
def check_average(nums, minimum_length, average):
modified_numbers = [number - average for number in nums]
current_sum = 0
previous_sum = 0
# Ensure that subarray of length >= min_length exists with average >= mid.
for i in range(minimum_length):
current_sum += modified_numbers[i]
if current_sum >= 0:
return True
for i in range(minimum_length, len(nums)):
current_sum += modified_numbers[i]
previous_sum += modified_numbers[i - minimum_length]
# Keep track of min_sum to check for positive sum subarray.
min_sum = min(0, previous_sum)
# The segment average is not less than the mid point.
if current_sum - min_sum >= 0:
return True
return False| Case | How to Handle |
|---|---|
| Empty input array | Return 0 if the array is empty, as there's no subarray. |
| k is larger than the array size | Return 0 because a subarray of size k cannot exist. |
| Array contains only one element, and k=1 | Return the single element's value as the maximum average. |
| Array contains all negative numbers | The maximum average will be the least negative number or the average of the k smallest negative numbers. |
| Array contains large positive and negative numbers, potential for overflow | Use double precision floating-point numbers to calculate sums and averages to avoid integer overflow. |
| Array contains all zeros | The maximum average subarray will be 0. |
| k is equal to the array size | Return the average of all elements in the array. |
| Floating-point precision issues during binary search | Use a small epsilon value for comparing doubles to handle potential floating-point precision errors. |