1+ """
2+ Problem: Product of Array Except Self
3+
4+ Goal:
5+ Given an integer array nums, return an array answer such that:
6+ answer[i] = product of all elements except nums[i]
7+
8+ ⚠️ Constraint:
9+ - Do NOT use division
10+ - Must run in O(n)
11+
12+ ---------------------------------------------------
13+ 🧠 HOW IT WORKS (Prefix + Postfix Concept)
14+ ---------------------------------------------------
15+
16+ Instead of division, we use two passes:
17+
18+ 👉 Prefix pass:
19+ For each index i, store product of all elements BEFORE i
20+
21+ 👉 Postfix pass:
22+ Multiply with product of all elements AFTER i
23+
24+ Example:
25+ nums = [1, 2, 3, 4]
26+
27+ Prefix:
28+ [1, 1, 2, 6]
29+
30+ Postfix:
31+ [24, 12, 4, 1]
32+
33+ Final Answer:
34+ [24, 12, 8, 6]
35+
36+ ---------------------------------------------------
37+ """
38+
39+ from typing import List
40+ import time
41+
42+
43+ # -------------------------------------------------
44+ # Approach 1: Prefix + Postfix (Optimal)
45+ # -------------------------------------------------
46+ class SolutionOptimal :
47+ def productExceptSelf (self , nums : List [int ]) -> List [int ]:
48+ n = len (nums )
49+ result = [1 ] * n
50+
51+ # Step 1: Prefix pass
52+ prefix = 1
53+ for i in range (n ):
54+ result [i ] = prefix
55+ prefix *= nums [i ]
56+
57+ # Step 2: Postfix pass
58+ postfix = 1
59+ for i in range (n - 1 , - 1 , - 1 ):
60+ result [i ] *= postfix
61+ postfix *= nums [i ]
62+
63+ return result
64+
65+
66+ # -------------------------------------------------
67+ # Approach 2: Brute Force (for understanding only)
68+ # -------------------------------------------------
69+ class SolutionBrute :
70+ def productExceptSelf (self , nums : List [int ]) -> List [int ]:
71+ n = len (nums )
72+ result = []
73+
74+ for i in range (n ):
75+ prod = 1
76+ for j in range (n ):
77+ if i != j :
78+ prod *= nums [j ]
79+ result .append (prod )
80+
81+ return result
82+
83+
84+ # -------------------------------------------------
85+ # Example + Runtime Measurement
86+ # -------------------------------------------------
87+ if __name__ == "__main__" :
88+ nums = [1 , 2 , 3 , 4 ]
89+
90+ # Optimal Approach
91+ start = time .time ()
92+ result1 = SolutionOptimal ().productExceptSelf (nums )
93+ end = time .time ()
94+ print ("Optimal Result :" , result1 )
95+ print ("Time Taken :" , (end - start ) * 1000 , "ms\n " )
96+
97+ # Brute Force Approach
98+ start = time .time ()
99+ result2 = SolutionBrute ().productExceptSelf (nums )
100+ end = time .time ()
101+ print ("Brute Result :" , result2 )
102+ print ("Time Taken :" , (end - start ) * 1000 , "ms" )
103+
104+
105+ """
106+ ---------------------------------------------------
107+ ⏱️ TIME COMPLEXITY
108+ ---------------------------------------------------
109+
110+ Optimal Approach:
111+ - O(n) → two passes
112+
113+ Brute Force:
114+ - O(n^2) → nested loops
115+
116+ ---------------------------------------------------
117+ 💾 SPACE COMPLEXITY
118+ ---------------------------------------------------
119+
120+ Optimal:
121+ - O(1) extra space (excluding output array)
122+
123+ Brute:
124+ - O(1)
125+
126+ ---------------------------------------------------
127+ ⚡ NOTE ON RUNTIME (ms)
128+ ---------------------------------------------------
129+ - Measured using time.time()
130+ - Depends on system performance
131+ - Optimal is MUCH faster than brute
132+
133+ ---------------------------------------------------
134+ 🔥 FINAL TAKEAWAY
135+ ---------------------------------------------------
136+
137+ Prefix + Postfix Pattern = No division needed
138+
139+ Used in:
140+ - Product problems
141+ - Range queries
142+ - Accumulation problems
143+
144+ ---------------------------------------------------
145+ """
0 commit comments