Skip to content

Commit 36e2531

Browse files
authored
[Arrays & Hashing][Product of Array Except Self] - Implement solution for Leetcode 238 (#12)
1 parent 8452e71 commit 36e2531

File tree

2 files changed

+150
-0
lines changed

2 files changed

+150
-0
lines changed
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
package productofarrayexceptself
2+
3+
// Time complexity: O(n^2), where n is the length of the input array.
4+
// Space complexity: O(n), for the output array.
5+
func ProductExceptSelfBruteForce(nums []int) []int {
6+
n := len(nums)
7+
result := make([]int, n)
8+
9+
for i := 0; i < n; i++ {
10+
product := 1
11+
for j := 0; j < n; j++ {
12+
if i != j {
13+
product *= nums[j]
14+
}
15+
}
16+
result[i] = product
17+
}
18+
return result
19+
}
20+
21+
// Time complexity: O(n), where n is the length of the input array.
22+
// Space complexity: O(1), for the output array (ignoring the output size).
23+
func ProductExceptSelfDivision(nums []int) []int {
24+
n := len(nums)
25+
result := make([]int, n)
26+
27+
totalProduct := 1
28+
zeroCount := 0
29+
30+
for _, num := range nums {
31+
if num != 0 {
32+
totalProduct *= num
33+
} else {
34+
zeroCount++
35+
}
36+
}
37+
38+
for i, num := range nums {
39+
if zeroCount > 1 {
40+
result[i] = 0
41+
} else if zeroCount == 1 {
42+
if num == 0 {
43+
result[i] = totalProduct
44+
} else {
45+
result[i] = 0
46+
}
47+
} else {
48+
result[i] = totalProduct / num
49+
}
50+
}
51+
return result
52+
}
53+
54+
// Time complexity: O(n), where n is the length of the input array.
55+
// Space complexity: O(n), for the output array.
56+
func ProductExceptSelfPrefixSuffix(nums []int) []int {
57+
n := len(nums)
58+
prefix := make([]int, n)
59+
suffix := make([]int, n)
60+
result := make([]int, n)
61+
62+
prefix[0] = 1
63+
for i := 1; i < n; i++ {
64+
prefix[i] = prefix[i-1] * nums[i-1]
65+
}
66+
67+
suffix[n-1] = 1
68+
for i := n - 2; i >= 0; i-- {
69+
suffix[i] = suffix[i+1] * nums[i+1]
70+
}
71+
72+
for i := 0; i < n; i++ {
73+
result[i] = prefix[i] * suffix[i]
74+
}
75+
return result
76+
}
77+
78+
// Time complexity: O(n), where n is the length of the input array.
79+
// Space complexity: O(1), for the output array (ignoring the output size).
80+
func ProductExceptSelfPrefixSuffixOptimal(nums []int) []int {
81+
n := len(nums)
82+
res := make([]int, n)
83+
84+
// Prefix pass
85+
res[0] = 1
86+
for i := 1; i < n; i++ {
87+
res[i] = res[i-1] * nums[i-1]
88+
}
89+
90+
// Suffix pass
91+
suffix := 1
92+
for i := n - 1; i >= 0; i-- {
93+
res[i] *= suffix
94+
suffix *= nums[i]
95+
}
96+
97+
return res
98+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package productofarrayexceptself
2+
3+
import (
4+
"reflect"
5+
"testing"
6+
)
7+
8+
func TestProductExceptSelf(t *testing.T) {
9+
cases := []struct {
10+
name string
11+
fn func([]int) []int
12+
nums []int
13+
expected []int
14+
}{
15+
// ProductExceptSelfBruteForce
16+
{"Brute Force - Basic", ProductExceptSelfBruteForce, []int{1, 2, 3, 4}, []int{24, 12, 8, 6}},
17+
{"Brute Force - One Zero", ProductExceptSelfBruteForce, []int{1, 2, 0, 4}, []int{0, 0, 8, 0}},
18+
{"Brute Force - Two Zeros", ProductExceptSelfBruteForce, []int{0, 2, 0, 4}, []int{0, 0, 0, 0}},
19+
{"Brute Force - Single", ProductExceptSelfBruteForce, []int{10}, []int{1}},
20+
{"Brute Force - Same Elements", ProductExceptSelfBruteForce, []int{3, 3, 3}, []int{9, 9, 9}},
21+
22+
// ProductExceptSelfDivision
23+
{"Division - Basic", ProductExceptSelfDivision, []int{1, 2, 3, 4}, []int{24, 12, 8, 6}},
24+
{"Division - One Zero", ProductExceptSelfDivision, []int{1, 2, 0, 4}, []int{0, 0, 8, 0}},
25+
{"Division - Two Zeros", ProductExceptSelfDivision, []int{0, 2, 0, 4}, []int{0, 0, 0, 0}},
26+
{"Division - Single", ProductExceptSelfDivision, []int{10}, []int{1}},
27+
{"Division - Same Elements", ProductExceptSelfDivision, []int{3, 3, 3}, []int{9, 9, 9}},
28+
29+
// ProductExceptSelfPrefixSuffix
30+
{"Prefix & Suffix - Basic", ProductExceptSelfPrefixSuffix, []int{1, 2, 3, 4}, []int{24, 12, 8, 6}},
31+
{"Prefix & Suffix - One Zero", ProductExceptSelfPrefixSuffix, []int{1, 2, 0, 4}, []int{0, 0, 8, 0}},
32+
{"Prefix & Suffix - Two Zeros", ProductExceptSelfPrefixSuffix, []int{0, 2, 0, 4}, []int{0, 0, 0, 0}},
33+
{"Prefix & Suffix - Single", ProductExceptSelfPrefixSuffix, []int{10}, []int{1}},
34+
{"Prefix & Suffix - Same Elements", ProductExceptSelfPrefixSuffix, []int{3, 3, 3}, []int{9, 9, 9}},
35+
36+
// ProductExceptSelfPrefixSuffixOptimal
37+
{"Prefix & Suffix Optimal - Basic", ProductExceptSelfPrefixSuffixOptimal, []int{1, 2, 3, 4}, []int{24, 12, 8, 6}},
38+
{"Prefix & Suffix Optimal - One Zero", ProductExceptSelfPrefixSuffixOptimal, []int{1, 2, 0, 4}, []int{0, 0, 8, 0}},
39+
{"Prefix & Suffix Optimal - Two Zeros", ProductExceptSelfPrefixSuffixOptimal, []int{0, 2, 0, 4}, []int{0, 0, 0, 0}},
40+
{"Prefix & Suffix Optimal - Single", ProductExceptSelfPrefixSuffixOptimal, []int{10}, []int{1}},
41+
{"Prefix & Suffix Optimal - Same Elements", ProductExceptSelfPrefixSuffixOptimal, []int{3, 3, 3}, []int{9, 9, 9}},
42+
}
43+
44+
for _, c := range cases {
45+
t.Run(c.name, func(t *testing.T) {
46+
got := c.fn(c.nums)
47+
if !reflect.DeepEqual(got, c.expected) {
48+
t.Errorf("%s failed: expected %v, got %v", c.name, c.expected, got)
49+
}
50+
})
51+
}
52+
}

0 commit comments

Comments
 (0)