Taro Logo

Minimum Average Difference

Medium
Meta logo
Meta
Topics:
Arrays

You are given a 0-indexed integer array nums of length n.

The average difference of the index i is the absolute difference between the average of the first i + 1 elements of nums and the average of the last n - i - 1 elements. Both averages should be rounded down to the nearest integer.

Return the index with the minimum average difference. If there are multiple such indices, return the smallest one.

Note:

  • The absolute difference of two numbers is the absolute value of their difference.
  • The average of n elements is the sum of the n elements divided (integer division) by n.
  • The average of 0 elements is considered to be 0.

For example, consider nums = [2,5,3,9,5,3]. The average differences are:

  • Index 0: |2 / 1 - (5 + 3 + 9 + 5 + 3) / 5| = |2 - 5| = 3
  • Index 1: |(2 + 5) / 2 - (3 + 9 + 5 + 3) / 4| = |3 - 5| = 2
  • Index 2: |(2 + 5 + 3) / 3 - (9 + 5 + 3) / 3| = |3 - 5| = 2
  • Index 3: |(2 + 5 + 3 + 9) / 4 - (5 + 3) / 2| = |4 - 4| = 0
  • Index 4: |(2 + 5 + 3 + 9 + 5) / 5 - 3 / 1| = |4 - 3| = 1
  • Index 5: |(2 + 5 + 3 + 9 + 5 + 3) / 6 - 0| = |4 - 0| = 4

The index with the minimum average difference is 3.

As another example, if nums = [0], the output is 0 because the average difference at index 0 is |0/1 - 0| = 0.

What is the most efficient algorithm to solve this problem and what are its space and time complexities?

Solution


Naive Solution

The most straightforward approach is to iterate through the nums array, and for each index i, calculate the average of the first i + 1 elements and the average of the last n - i - 1 elements. Then, compute the absolute difference between these two averages and keep track of the minimum average difference encountered so far, along with its corresponding index.

Code (Python)

def min_avg_diff_naive(nums):
    n = len(nums)
    min_diff = float('inf')
    min_index = -1

    for i in range(n):
        # Calculate average of first i+1 elements
        first_avg = sum(nums[:i+1]) // (i + 1)

        # Calculate average of last n-i-1 elements
        if i < n - 1:
            last_avg = sum(nums[i+1:]) // (n - i - 1)
        else:
            last_avg = 0  # Average of 0 elements is 0

        # Calculate absolute difference
        diff = abs(first_avg - last_avg)

        # Update minimum difference and index if necessary
        if diff < min_diff:
            min_diff = diff
            min_index = i

    return min_index

Time Complexity

O(n^2) because for each index i, we are calculating the sum of subarrays which takes O(n) time within the loop that iterates n times.

Space Complexity

O(1) since we are only using a constant amount of extra space.

Optimal Solution

To optimize the solution, we can precompute the total sum of the array. Then, as we iterate through the array, we can maintain a running sum of the first i + 1 elements. This allows us to calculate the average of the first i + 1 elements and the average of the last n - i - 1 elements in O(1) time, reducing the overall time complexity.

Code (Python)

def min_avg_diff(nums):
    n = len(nums)
    total_sum = sum(nums)
    current_sum = 0
    min_diff = float('inf')
    min_index = -1

    for i in range(n):
        current_sum += nums[i]
        first_avg = current_sum // (i + 1)

        if i < n - 1:
            last_avg = (total_sum - current_sum) // (n - i - 1)
        else:
            last_avg = 0

        diff = abs(first_avg - last_avg)

        if diff < min_diff:
            min_diff = diff
            min_index = i

    return min_index

Time Complexity

O(n) because we iterate through the array once to calculate the total sum and then iterate again to find the minimum average difference. Each calculation within the loop takes O(1) time.

Space Complexity

O(1) since we are only using a constant amount of extra space.

Edge Cases

  • Empty Array: Although the problem statement says 1 <= nums.length <= 10^5, it's good to consider an empty array. The code will not work with an empty array, but the problem statement excludes it.
  • Single Element Array: If the array contains only one element, the average difference will be the absolute difference between the element itself and 0.
  • Array with All Zeros: The algorithm should correctly handle arrays where all elements are zero.
  • Large Numbers: The sums of the elements could potentially be large, so using long/long long (in C++) or equivalent data types to avoid integer overflow is essential if the problem constraints allowed a larger upper limit for the numbers in nums.

Summary

The optimal solution involves precomputing the total sum of the array to achieve a linear time complexity of O(n) and constant space complexity of O(1). This improves upon the naive approach's O(n^2) time complexity.