HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

TapeEquilibrium implementation

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
implementationtapeequilibriumstackoverflow

Problem

I took a test at Codility called TapeEquilibrium. The task description that I received can be seen here.

I came up with a solution that worked, and I was pretty happy with. However, the performance was apparently awful. The expected time complexity is apparently supposed to be \$O(N)\$, but I got \$O(N * N)\$. I'm not quite sure what exactly that means, but I've heard about it several times.

I'd like some help on improving my solution and get information about what I did wrong and how it could be done better, and why. I'm doing this to learn and improve.

public int solution(int[] A) {
    int min = Int32.MaxValue;
    for (int i = 0; i < A.Length - 1; i++) {
        // p = i + 1            
        int part1 = 0, part2 = 0;
        for (int j = 0; j <= i; j++) part1 += A[j];
        for (int j = i + 1; j <= A.Length - 1; j++) part2 += A[j];

        int val = Math.Abs(part1 - part2);
        if (val < min) min = val;
    }
    return min;
}

Solution

Style

Initializing of multiple variables on one line removes readability.

Writing for loops on one line removes readability.

Dead code should be deleted (// p = i + 1)

Bug

It seems that you have a little unnoticed bug in your code. Your loop

for (int i = 0; i < A.Length - 1; i++) {


misses the last element of your array.

Problem

Let us assume we have an array A containing 8 elements like

3 5 7 2 5 2 1 3

The ideal divider would be if the arrays left half summed up would be equal to the right half summed up.

Unfortunatetly here

sumLeft = A[0] + A[1] + A[2] + A[3] == 17

sumRight = A[4] + A[5] + A[6] + A[7] == 11

difference = sumLeft - sumRight == 6

So as we see that the left half > right half let us take the last element of the left side and check if 2 * A[half-1] sumRight

difference = sumLeft - sumRight;
while (2*A[currentHalf-1] <= difference)
{
    currentHalf = currentHalf -1;
    sumLeft = sumLeft - A[currentHalf]
    sumRight = sumRight + A[currentHalf]
    difference = difference - 2 * A[currentHalf];
}


EDIT : Based on @Dmitry's comments I rechecked the algorithm and came to the result that this algorithm only works for positive numbers.

And my implementation of the above

public int solution(int[] A)
{
    int length = A.Length;
    int sumLeft = 0;
    int sumRight = 0;

    int currentArrayHalf = length / 2;

    for (int i = 0; i  sumRight)
    {
        step = -1;
        if (isEven)
        {
            currentArrayHalf--;
        }
    }

    int difference = Math.Abs(sumLeft - sumRight);
    if (difference == 0) { return difference; }

    while (currentArrayHalf >= 0 && currentArrayHalf < length && 2 * A[currentArrayHalf] <= difference)
    {
        sumLeft = sumLeft - A[currentArrayHalf];
        sumRight = sumRight + A[currentArrayHalf];
        difference = difference - 2 * A[currentArrayHalf];
        currentArrayHalf = currentArrayHalf + step;
    }

    return difference;
}

Code Snippets

for (int i = 0; i < A.Length - 1; i++) {
difference = sumLeft - sumRight;
while (2*A[currentHalf-1] <= difference)
{
    currentHalf = currentHalf -1;
    sumLeft = sumLeft - A[currentHalf]
    sumRight = sumRight + A[currentHalf]
    difference = difference - 2 * A[currentHalf];
}
public int solution(int[] A)
{
    int length = A.Length;
    int sumLeft = 0;
    int sumRight = 0;

    int currentArrayHalf = length / 2;

    for (int i = 0; i < currentArrayHalf; i++)
    {
        sumLeft = sumLeft + A[i];
        sumRight = sumRight + A[i + currentArrayHalf];
    }

    Boolean isEven = length % 2 == 0;

    if (!isEven) { sumRight = sumRight + A[length - 1]; }

    int step = 1;
    if (sumLeft > sumRight)
    {
        step = -1;
        if (isEven)
        {
            currentArrayHalf--;
        }
    }

    int difference = Math.Abs(sumLeft - sumRight);
    if (difference == 0) { return difference; }

    while (currentArrayHalf >= 0 && currentArrayHalf < length && 2 * A[currentArrayHalf] <= difference)
    {
        sumLeft = sumLeft - A[currentArrayHalf];
        sumRight = sumRight + A[currentArrayHalf];
        difference = difference - 2 * A[currentArrayHalf];
        currentArrayHalf = currentArrayHalf + step;
    }

    return difference;
}

Context

StackExchange Code Review Q#70701, answer score: 7

Revisions (0)

No revisions yet.