Skip to main content
mathjax is your god and you know it
Source Link
Pimgd
  • 22.3k
  • 5
  • 66
  • 144

The trick to this problem is in the algorithm. A solution of O(n)\$O(n)\$ complexity is available if you process the data in a 'clever' way. Consider the following algorithm:

  • create a new array of the same size, call it sum
  • populate the sum array with the sum of all values to the left in the original data array
  • Once the sum array is fully populated, you will know what the total sum is for the array.
  • this allows you to determine what the balance-point-sum is, it will be half of the total.
  • you may be tempted to just binary search the sum array for the place that is half the total, but this will fail if there are negative values in the input array.
  • the only solution is to scan the sums looking for half the value, with some short-circuit if there is an exact half found.

Putting it together as code, it looks like:

public static final int tapeEquilibrium(int[] data) {
    if (data.length < 3) {
        // rules indicate 0 < P < N which implies at least 3-size array
        throw new IllegalStateException("Need minimum 3-size array input");
    }
    int[] sums = new int[data.length];
    for (int i = 1; i < sums.length; i++) {
        sums[i] = sums[i - 1] + data[i - 1];
    }
    int total = sums[sums.length - 1] + data[data.length - 1];
    int min = Integer.MAX_VALUE;
    for (int i = 0; i < sums.length; i++) {
        int diff = Math.abs((total - sums[i]) - sums[i]);
        if (diff == 0) {
            return 0;
        }
        if (diff < min) {
            min = diff;
        }
    }
    return min;
}

The trick to this problem is in the algorithm. A solution of O(n) complexity is available if you process the data in a 'clever' way. Consider the following algorithm:

  • create a new array of the same size, call it sum
  • populate the sum array with the sum of all values to the left in the original data array
  • Once the sum array is fully populated, you will know what the total sum is for the array.
  • this allows you to determine what the balance-point-sum is, it will be half of the total.
  • you may be tempted to just binary search the sum array for the place that is half the total, but this will fail if there are negative values in the input array.
  • the only solution is to scan the sums looking for half the value, with some short-circuit if there is an exact half found.

Putting it together as code, it looks like:

public static final int tapeEquilibrium(int[] data) {
    if (data.length < 3) {
        // rules indicate 0 < P < N which implies at least 3-size array
        throw new IllegalStateException("Need minimum 3-size array input");
    }
    int[] sums = new int[data.length];
    for (int i = 1; i < sums.length; i++) {
        sums[i] = sums[i - 1] + data[i - 1];
    }
    int total = sums[sums.length - 1] + data[data.length - 1];
    int min = Integer.MAX_VALUE;
    for (int i = 0; i < sums.length; i++) {
        int diff = Math.abs((total - sums[i]) - sums[i]);
        if (diff == 0) {
            return 0;
        }
        if (diff < min) {
            min = diff;
        }
    }
    return min;
}

The trick to this problem is in the algorithm. A solution of \$O(n)\$ complexity is available if you process the data in a 'clever' way. Consider the following algorithm:

  • create a new array of the same size, call it sum
  • populate the sum array with the sum of all values to the left in the original data array
  • Once the sum array is fully populated, you will know what the total sum is for the array.
  • this allows you to determine what the balance-point-sum is, it will be half of the total.
  • you may be tempted to just binary search the sum array for the place that is half the total, but this will fail if there are negative values in the input array.
  • the only solution is to scan the sums looking for half the value, with some short-circuit if there is an exact half found.

Putting it together as code, it looks like:

public static final int tapeEquilibrium(int[] data) {
    if (data.length < 3) {
        // rules indicate 0 < P < N which implies at least 3-size array
        throw new IllegalStateException("Need minimum 3-size array input");
    }
    int[] sums = new int[data.length];
    for (int i = 1; i < sums.length; i++) {
        sums[i] = sums[i - 1] + data[i - 1];
    }
    int total = sums[sums.length - 1] + data[data.length - 1];
    int min = Integer.MAX_VALUE;
    for (int i = 0; i < sums.length; i++) {
        int diff = Math.abs((total - sums[i]) - sums[i]);
        if (diff == 0) {
            return 0;
        }
        if (diff < min) {
            min = diff;
        }
    }
    return min;
}
Source Link
rolfl
  • 97.5k
  • 17
  • 218
  • 418

The trick to this problem is in the algorithm. A solution of O(n) complexity is available if you process the data in a 'clever' way. Consider the following algorithm:

  • create a new array of the same size, call it sum
  • populate the sum array with the sum of all values to the left in the original data array
  • Once the sum array is fully populated, you will know what the total sum is for the array.
  • this allows you to determine what the balance-point-sum is, it will be half of the total.
  • you may be tempted to just binary search the sum array for the place that is half the total, but this will fail if there are negative values in the input array.
  • the only solution is to scan the sums looking for half the value, with some short-circuit if there is an exact half found.

Putting it together as code, it looks like:

public static final int tapeEquilibrium(int[] data) {
    if (data.length < 3) {
        // rules indicate 0 < P < N which implies at least 3-size array
        throw new IllegalStateException("Need minimum 3-size array input");
    }
    int[] sums = new int[data.length];
    for (int i = 1; i < sums.length; i++) {
        sums[i] = sums[i - 1] + data[i - 1];
    }
    int total = sums[sums.length - 1] + data[data.length - 1];
    int min = Integer.MAX_VALUE;
    for (int i = 0; i < sums.length; i++) {
        int diff = Math.abs((total - sums[i]) - sums[i]);
        if (diff == 0) {
            return 0;
        }
        if (diff < min) {
            min = diff;
        }
    }
    return min;
}