Minimum Average Difference

Updated on 11 June, 2025
Minimum Average Difference header image

Problem Statement

Given an integer array nums which is 0-indexed and has length n, the task is to compute the "average difference" for each index i. This average difference is defined as the absolute difference between the average of the first i + 1 elements and the average of the remaining n - i - 1 elements, with both averages rounded down to the nearest integer. The challenge is to find the index where this average difference is minimized. If several indices have the same minimal average difference, the smallest index among them should be returned.

To sum up:

  • Calculate the rounded average of the first i + 1 elements.
  • Calculate the rounded average of the last n - i - 1 elements.
  • Compute their absolute difference.
  • Find the index with the minimum such difference.

The special note clarifies:

  • The average difference uses absolute value.
  • Averages are computed using integer division.
  • The average of no elements (empty subset) is deemed to be 0.

Examples

Example 1

Input:

nums = [2,5,3,9,5,3]

Output:

3

Explanation:

- The average difference of index 0 is: |2 / 1 - (5 + 3 + 9 + 5 + 3) / 5| = |2 / 1 - 25 / 5| = |2 - 5| = 3.
- The average difference of index 1 is: |(2 + 5) / 2 - (3 + 9 + 5 + 3) / 4| = |7 / 2 - 20 / 4| = |3 - 5| = 2.
- The average difference of index 2 is: |(2 + 5 + 3) / 3 - (9 + 5 + 3) / 3| = |10 / 3 - 17 / 3| = |3 - 5| = 2.
- The average difference of index 3 is: |(2 + 5 + 3 + 9) / 4 - (5 + 3) / 2| = |19 / 4 - 8 / 2| = |4 - 4| = 0.
- The average difference of index 4 is: |(2 + 5 + 3 + 9 + 5) / 5 - 3 / 1| = |24 / 5 - 3 / 1| = |4 - 3| = 1.
- The average difference of index 5 is: |(2 + 5 + 3 + 9 + 5 + 3) / 6 - 0| = |27 / 6 - 0| = |4 - 0| = 4.
The average difference of index 3 is the minimum average difference so return 3.

Example 2

Input:

nums = [0]

Output:

0

Explanation:

The only index is 0 so return 0.
The average difference of index 0 is: |0 / 1 - 0| = |0 - 0| = 0.

Constraints

  • 1 <= nums.length <= 105
  • 0 <= nums[i] <= 105

Approach and Intuition

To solve this problem, observe the following steps and insights derived from the examples provided:

  1. Prefix and Suffix Sums:

    • Calculate the prefix sum for the array which will help in quick computation of the sum of the first i elements.
    • Similarly, compute a suffix sum for efficient calculation of the sum of the last elements starting from any index.
  2. Iterating through Indices:

    • For each index i, calculate the average of the first i+1 elements. This average can be get by dividing the prefix sum by i+1.
    • Calculate the average of the remaining elements which start from index i+1 to the end. This average is the suffix sum starting from i+1 divided by n-i-1.
  3. Compute the Differences and Keep Track of Minimums:

    • For each index, compute the absolute difference of the two averages.
    • Keep a track of the minimum difference encountered so far and update the index associated with this minimum difference whenever a new lower minimum is found.
  4. Edge Cases and Zero-Length Averages:

    • Handle cases as per the rules where if any of the averages have zero elements, the average is considered to be 0.

From these steps, it's evident that the algorithm majorly depends on efficiently calculating the sums and differences for each index, which is optimized using the prefix and suffix sums. The problem constraints indicate that the solution needs to be efficient enough to handle up to 100,000 elements, making this method suitable within the acceptable performance limits.

Solutions

  • C++
  • Java
  • JavaScript
  • Python
cpp
class Solution {
public:
    int findMinAvgDiffIndex(vector<int>& elements) {
        int count = elements.size();
        int bestIndex = -1;
        int lowestAvgDiff = numeric_limits<int>::max();
        long long prefixSum = 0;

        long long totalElementsSum = 0;
        for (int i = 0; i < count; ++i) {
            totalElementsSum += elements[i];
        }

        for (int i = 0; i < count; ++i) {
            prefixSum += elements[i];
            long long avgLeft = prefixSum / (i + 1);
            long long avgRight = totalElementsSum - prefixSum;
            if (i != count - 1) {
                avgRight /= (count - i - 1);
            }
            int difference = int(abs(avgLeft - avgRight));
            if (difference < lowestAvgDiff) {
                lowestAvgDiff = difference;
                bestIndex = i;
            }
        }

        return bestIndex;
    }
};

The given C++ solution defines a method intended to determine the index at which the average difference between the sums of the two partitions split by this index is minimized. Here’s a comprehensive breakdown of how the solution works and what each segment of the code accomplishes:

  • This solution implements a single public function named findMinAvgDiffIndex within a class named Solution. The function accepts one argument: a vector of integers referred to as elements.

  • Initialized variables are:

    • count to store the number of elements in the input vector.
    • bestIndex, initialized to -1, used to store the index with the minimal average difference.
    • lowestAvgDiff, set to the maximum possible value for an integer initially, to store the smallest average difference found.
    • prefixSum to accumulate the sum as the function iterates through the vector, starting at zero.
    • totalElementsSum also beginning at zero, intended to compute the sum of all elements in the vector.
  • The first loop totals all elements in the input vector to totalElementsSum. This sum represents the total value of elements that will be used to compute the average of the right partition of the array.

  • The main computation occurs in the second loop, where:

    • prefixSum accumulates the sum of elements from the start up to the current index. This sum represents the left partition.
    • avgLeft calculates the average of the left partition by dividing prefixSum by the number of elements in this partition (i.e., index + 1).
    • avgRight calculates the average of the right partition. It determines the sum of this partition by subtracting prefixSum from totalElementsSum. If the current index isn't the last one (i.e., i != count - 1), it divides this sum by the number of elements in the right partition (i.e., count - i - 1).
    • The absolute difference between avgLeft and avgRight is computed as difference.
    • If this difference is smaller than lowestAvgDiff, then lowestAvgDiff is updated to this difference, and bestIndex to the current index i.
  • Finally, the function returns bestIndex, the index position where the minimum average difference occurs, providing a solution to the problem.

This method effectively leverages sum and partitioning principles, ensuring an efficient pass through the data while maintaining calculations that will deliver the correct index or partition point in the array with minimum average difference.

java
class Solution {
    public int findMinAvgDiffIndex(int[] nums) {
        int size = nums.length;
        int bestIndex = -1;
        int leastDiff = Integer.MAX_VALUE;
        long sumSoFar = 0;

        long total = 0;
        for (int i = 0; i < size; i++) {
            total += nums[i];
        }

        for (int i = 0; i < size; i++) {
            sumSoFar += nums[i];

            long averageLeft = sumSoFar / (i + 1);
            long averageRight = total - sumSoFar;
            if (i < size - 1) {
                averageRight /= (size - i - 1);
            }

            int diff = (int) Math.abs(averageLeft - averageRight);
            if (diff < leastDiff) {
                leastDiff = diff;
                bestIndex = i;
            }
        }

        return bestIndex;
    }
}

The given Java program calculates the index in an array where the absolute difference between the average of elements to the left including the element at that index, and the average of elements to the right excluding the element at that index, is minimized. Here’s a breakdown of how the solution approaches the problem:

  • Initialize the total sum of elements in the array.
  • Iterate through each element, simultaneously updating the sum of elements seen so far.
  • For each index:
    • Compute the average of elements from the start to the current index.
    • Compute the average of elements after the current index to the end of the array.
    • Calculate the absolute difference between the two averages.
    • Update the minimum difference and the associated index if the current difference is smaller than the previously recorded minimum.

Key considerations include:

  • Handling of edge cases where the index is at the beginning or end of the array.
  • Efficient computation of the sums and averages to minimize redundant calculations.

This approach ensures the program efficiently finds the index with the minimum average difference, utilizing O(n) time complexity where n is the number of elements in the input array, thanks to only making two passes through the data.

js
let minAvgDiffIndex = function(array) {
    let length = array.length;
    let resultIndex = -1;
    let minDifference = Number.MAX_SAFE_INTEGER;
    let prefixSum = 0;
    let totalArraySum = 0;

    // Calculate total sum
    for (let i = 0; i < length; ++i) {
        totalArraySum += array[i];
    }

    for (let i = 0; i < length; ++i) {
        prefixSum += array[i];

        // Calculate average of the left side
        let leftAvg = Math.floor(prefixSum / (i + 1));

        // Calculate average of the right side
        let rightAvg = totalArraySum - prefixSum;
        if (i != length - 1) {
            rightAvg = Math.floor(rightAvg / (length - i - 1));
        }

        let difference = Math.abs(leftAvg - rightAvg);

        // Update minimum difference and result index
        if (difference < minDifference) {
            minDifference = difference;
            resultIndex = i;
        }
    }

    return resultIndex;
};

The goal is to determine the index in an array where the absolute difference between the average of the elements on the left and the average of the elements on the right is minimized. The function minAvgDiffIndex in JavaScript achieves this by iterating through each element as a potential division point between the left and right sides of the array.

  • First, compute the total sum of the array to use for subsequent average calculations.
  • Then, iterate through each element in the array, using it to split the array into left and right parts:
    1. Update a running sum (prefixSum) as you go, which represents the sum of the current and all previous elements.
    2. Calculate the left average using the prefixSum divided by the number of elements to the left, including the current element.
    3. Compute the right average from the total array sum minus the prefixSum, divided by the number of elements to the right.
    4. Compare the absolute difference between the left and right averages to the smallest difference found in previous steps.
    5. If this difference is smaller, update the minimum difference and the index where this occurs.
  • Return the index at which the minimum average difference was found.

This procedure efficiently helps identify the point in an array that minimally disrupts the balance in terms of their averages, essential for applications that require partitioning of data into almost equal average subsets.

python
class Solution:
    def find_min_avg_difference_idx(self, numbers: List[int]) -> int:
        number_count = len(numbers)
        min_difference_idx = -1
        smallest_avg_diff = float('inf')
        prefix_sum_so_far = 0

        total_numbers_sum = sum(numbers)
        
        for i in range(number_count):
            prefix_sum_so_far += numbers[i]
            
            average_left = prefix_sum_so_far // (i + 1)
            
            remaining_sum = total_numbers_sum - prefix_sum_so_far
            if i != number_count - 1:
                average_right = remaining_sum // (number_count - i - 1)
            else:
                average_right = 0
            
            current_avg_diff = abs(average_left - average_right)
            
            if current_avg_diff < smallest_avg_diff:
                smallest_avg_diff = current_avg_diff
                min_difference_idx = i

        return min_difference_idx

This Python solution addresses the problem of finding the index in an array where the average difference between the sum of the numbers to the left of the index and the sum of the numbers to the right is minimized. Follow these general steps in the code's logic:

  1. Initialize key variables including a counter for the total sum of numbers and variables to track the smallest average difference and corresponding index.
  2. Calculate the total sum of the array to facilitate computations involving sums to the right of the current index.
  3. Loop through each element in the array:
    • Update the prefix sum, which is the sum of numbers up to the current index.
    • Compute the average of the numbers to the left of the current index.
    • Determine the sum and average of numbers to the right of the index by subtracting the prefix sum from the total sum and adjusting for the count of the remaining elements.
    • Calculate the absolute difference between the left and right averages for the current index.
    • If this difference is smaller than previously recorded ones, update the smallest difference and the corresponding index.
  4. Return the index that represents the minimum average difference.

The solution effectively uses cumulative sums and iterative comparison to find the index that minimizes the average difference, which can provide efficient resolution suitable for large datasets.

Comments

No comments yet.