Intuition

Brute force, but it doesn’t work.

Approach

I had to read the solution. The key is math, the order of a product operation do not affect the final result. Visualization makes it easier.

A*B*C*D = (A*B)*(C*D)

Let’s see one example in action. Consider the following array

n=[2,2,3,2,2]

When calculating the answer for n[2], we are calculating the product of two separated grous (2*2) * (2*2), left L and right R independently.

First we do all the lefts, then all rights. The result would be these two arrays:

L = [1,2,4,12,24]
R = [24,12,4,2,1]

Now because each array is the product of all left elements, and all right elements, the asnwer to the problem is

answer[ith] = L[ith] * R[ith]

[ \begin{aligned} KL(\hat{y} || y) &= \sum_{c=1}^{M}\hat{y}_c \log{\frac{\hat{y}_c}{y_c}} \ JS(\hat{y} || y) &= \frac{1}{2}(KL(y||\frac{y+\hat{y}}{2}) + KL(\hat{y}||\frac{y+\hat{y}}{2})) \end{aligned} ]

Complexity

  • Time complexity: O(n)

  • Space complexity: O(n)

Code

class Solution(object):
    def productExceptSelf(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        m=len(nums)
        answer = [1] * m
        # Brute force Solution O(n2)
        # for i in range(m):
        #     for j in range(m):
        #         if j==i:
        #             continue
        #         answer[i] *= nums[j]

        L = [1] * m
        R = [1] * m
        product = 1
        for i in range(m):
            if i-1 >= 0:
                L[i] = product
            product *= nums[i]

        product = 1
        for i in reversed(range(m)):
            if i-1 < m:
                R[i] = product
            product *= nums[i]
        for i in range(m):
            answer[i] = L[i] * R[i]

        return answer