Product of Array Except Self in Python

The Product of Array Except Self problem requires finding an array where each element is the product of all other elements in the original array, without using division. For input [1,2,3,4], the output should be [24,12,8,6].

Algorithm Overview

The solution uses two passes to calculate left and right products efficiently ?

  • Create a right_mul array to store cumulative products from right to left
  • Use a prefix variable to track left products while building the final result
  • Combine left and right products to get the answer

Step-by-Step Implementation

class Solution:
    def productExceptSelf(self, nums):
        # Step 1: Create right_mul array for right side products
        right_multiply = [0] * len(nums)
        right_multiply[-1] = nums[-1]
        
        # Fill right_multiply from right to left
        for i in range(1, len(nums)):
            right_multiply[len(nums) - i - 1] = right_multiply[len(nums) - i] * nums[len(nums) - i - 1]
        
        # Step 2: Create output array combining left and right products
        output = [0] * len(nums)
        prefix = 1
        current_index = 0
        
        # Calculate products using left prefix and right array
        while current_index < len(output) - 1:
            output[current_index] = prefix * right_multiply[current_index + 1]
            prefix *= nums[current_index]
            current_index += 1
        
        # Handle last element
        output[-1] = prefix
        return output

# Test the solution
solution = Solution()
result = solution.productExceptSelf([1, 3, 5, 7, 9])
print("Input:", [1, 3, 5, 7, 9])
print("Output:", result)
Input: [1, 3, 5, 7, 9]
Output: [945, 315, 189, 135, 105]

How It Works

Let's trace through the algorithm with [1, 3, 5, 7, 9] ?

def productExceptSelf_detailed(nums):
    print(f"Original array: {nums}")
    
    # Step 1: Build right_multiply array
    right_multiply = [0] * len(nums)
    right_multiply[-1] = nums[-1]
    print(f"Initial right_multiply: {right_multiply}")
    
    for i in range(1, len(nums)):
        idx = len(nums) - i - 1
        right_multiply[idx] = right_multiply[idx + 1] * nums[idx]
        print(f"right_multiply[{idx}] = {right_multiply[idx + 1]} * {nums[idx]} = {right_multiply[idx]}")
    
    print(f"Final right_multiply: {right_multiply}")
    
    # Step 2: Build output using left prefix
    output = [0] * len(nums)
    prefix = 1
    
    for i in range(len(nums) - 1):
        output[i] = prefix * right_multiply[i + 1]
        print(f"output[{i}] = {prefix} * {right_multiply[i + 1]} = {output[i]}")
        prefix *= nums[i]
        print(f"prefix updated to: {prefix}")
    
    output[-1] = prefix
    print(f"output[{len(nums)-1}] = {prefix}")
    
    return output

result = productExceptSelf_detailed([1, 3, 5, 7, 9])
print(f"Final result: {result}")
Original array: [1, 3, 5, 7, 9]
Initial right_multiply: [0, 0, 0, 0, 9]
right_multiply[3] = 9 * 7 = 63
right_multiply[2] = 63 * 5 = 315
right_multiply[1] = 315 * 3 = 945
right_multiply[0] = 945 * 1 = 945
Final right_multiply: [945, 945, 315, 63, 9]
output[0] = 1 * 945 = 945
prefix updated to: 1
output[1] = 1 * 315 = 315
prefix updated to: 3
output[2] = 3 * 63 = 189
prefix updated to: 15
output[3] = 15 * 9 = 135
prefix updated to: 105
output[4] = 105
Final result: [945, 315, 189, 135, 105]

Alternative Approach with Two Arrays

A more intuitive approach uses separate left and right product arrays ?

def productExceptSelf_twoArrays(nums):
    n = len(nums)
    left = [1] * n
    right = [1] * n
    result = []
    
    # Fill left products
    for i in range(1, n):
        left[i] = left[i - 1] * nums[i - 1]
    
    # Fill right products
    for i in range(n - 2, -1, -1):
        right[i] = right[i + 1] * nums[i + 1]
    
    # Combine left and right
    for i in range(n):
        result.append(left[i] * right[i])
    
    return result

# Test both approaches
nums = [2, 3, 4, 5]
print("Two arrays approach:", productExceptSelf_twoArrays(nums))

solution = Solution()
print("Optimized approach:", solution.productExceptSelf(nums))
Two arrays approach: [60, 40, 30, 24]
Optimized approach: [60, 40, 30, 24]

Conclusion

The optimized solution uses O(1) extra space by combining left products with a pre-computed right products array. This approach efficiently solves the problem in O(n) time without using division.

Updated on: 2026-03-25T08:01:52+05:30

1K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements