Question:

There is an array A[N] of N numbers. You have to compose an array Output[N] such that Output[i] will be equal to multiplication of all the elements of A[N] except A[i]. Solve it without division operator and in O(n).


For example Output[0] will be multiplication of A[1] to A[N-1] and Output[1] will be multiplication of A[0] and from A[2] to A[N-1].


Example:

A: {4, 3, 2, 1, 2}

OUTPUT: {12, 16, 24, 48, 24}


http://leetcode.com/2010/04/multiplication-of-numbers.html

// Time: O(n)
int[] calc(int[] A)
{
    // Assumptions:
    // A is not null, not empty.
    int len = A.length;
    
    // Define B[i] = A[0] * A[1] * ... * A[i];
    // B[0] = A[0];
    // B[i] = B[i - 1] * A[i];
    //
    // Similarly, define C[i] = A[i] * A[i + 1] * ... * A[len - 1]
    int[] B = new int[len];
    B[0] = A[0];
    
    int[] C = new int[len];
    C[len - 1] = A[len - 1];
    
    for (int i = 0 ; i < len ; i ++)
    {
        if (i > 0)
            B[i] = B[i - 1] * A[i];

        int j = len - 1 - i;
        if (j < len - 1)
            C[j] = C[j + 1] * A[j];
    }
    
    int[] toReturn = new int[len];
    for (int i = 0 ; i < len - 1 ; i ++)
    {
        int a = i == 0 ? 1 : B[i - 1];
        int b = i == len - 1 ? 1 : C[i + 1];
        toReturn[i] = a * b;
    }
    return toReturn;
}

// See the link as a better solution without extra space
int[] calc(int[] A)
{
    int len = A.length;
    
    int left = 1; // A[0] * A[1] * ... A[i - 1]
    int right = 1; // A[i + 1] * ... A[len - 1]
    // O[i] = left * right;
    
    int[] O = new int[len];
    Arrays.fill(O, 1);
    
    for (int i = 0 ; i < len ; i ++)
    {
        O[i] *= left;
        O[len - 1 - i] *= right;
        left *= A[i];
        right *= A[len - 1 - i];
    }
}