Skip to content

Commit 62ae40f

Browse files
committed
Product of array except self
1 parent 9b3a1e7 commit 62ae40f

File tree

2 files changed

+169
-0
lines changed

2 files changed

+169
-0
lines changed
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// 238. Product of array except self
2+
// Topics: 'Prefix Sum', 'Array'
3+
// Level: 'Medium'
4+
5+
// Given an integer array nums, return an array answer such that answer[i] is equal to the product of all the elements of nums except nums[i].
6+
7+
// The product of any prefix or suffix of nums is guaranteed to fit in a 32-bit integer.
8+
9+
// You must write an algorithm that runs in O(n) time and without using the division operation.
10+
11+
// Example 1:
12+
13+
// Input: nums = [1,2,3,4]
14+
// Output: [24,12,8,6]
15+
16+
// Example 2:
17+
18+
// Input: nums = [-1,1,0,-3,3]
19+
// Output: [0,0,9,0,0]
20+
21+
// Constraints:
22+
23+
// 2 <= nums.length <= 105
24+
// -30 <= nums[i] <= 30
25+
// The input is generated such that answer[i] is guaranteed to fit in a 32-bit integer.
26+
27+
// Follow up: Can you solve the problem in O(1) extra space complexity? (The output array does not count as extra space for space complexity analysis.)
28+
29+
package productofarrayexceptself
30+
31+
func productExceptSelf(nums []int) []int {
32+
res := make([]int, len(nums))
33+
34+
prefix := 1
35+
for i := range nums {
36+
prefix *= nums[i]
37+
res[i] = prefix
38+
}
39+
suffix := 1
40+
for i := len(nums) - 1; i >= 0; i-- {
41+
p := 1
42+
if (i - 1) >= 0 {
43+
p = res[i-1]
44+
}
45+
res[i] = p * suffix
46+
suffix *= nums[i]
47+
}
48+
49+
return res
50+
}
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
package productofarrayexceptself
2+
3+
import (
4+
"reflect"
5+
"testing"
6+
)
7+
8+
func TestProductExceptSelf(t *testing.T) {
9+
tests := []struct {
10+
name string
11+
nums []int
12+
want []int
13+
}{
14+
{
15+
name: "example 1 - basic positive numbers",
16+
nums: []int{1, 2, 3, 4},
17+
want: []int{24, 12, 8, 6},
18+
},
19+
{
20+
name: "example 2 - with zero in middle",
21+
nums: []int{-1, 1, 0, -3, 3},
22+
want: []int{0, 0, 9, 0, 0},
23+
},
24+
{
25+
name: "two elements",
26+
nums: []int{2, 3},
27+
want: []int{3, 2},
28+
},
29+
{
30+
name: "all ones",
31+
nums: []int{1, 1, 1, 1},
32+
want: []int{1, 1, 1, 1},
33+
},
34+
{
35+
name: "zero at start",
36+
nums: []int{0, 2, 3},
37+
want: []int{6, 0, 0},
38+
},
39+
{
40+
name: "zero at end",
41+
nums: []int{2, 3, 0},
42+
want: []int{0, 0, 6},
43+
},
44+
{
45+
name: "multiple zeros",
46+
nums: []int{0, 0, 2, 3},
47+
want: []int{0, 0, 0, 0},
48+
},
49+
{
50+
name: "negative numbers",
51+
nums: []int{-2, -3, -4},
52+
want: []int{12, 8, 6},
53+
},
54+
{
55+
name: "mixed positive and negative",
56+
nums: []int{2, -3, 4, -5},
57+
want: []int{60, -40, 30, -24},
58+
},
59+
{
60+
name: "single negative with positives",
61+
nums: []int{1, -2, 3, 4},
62+
want: []int{-24, 12, -8, -6},
63+
},
64+
{
65+
name: "larger array",
66+
nums: []int{1, 2, 3, 4, 5},
67+
want: []int{120, 60, 40, 30, 24},
68+
},
69+
{
70+
name: "array with one and zero",
71+
nums: []int{1, 0},
72+
want: []int{0, 1},
73+
},
74+
{
75+
name: "maximum negative value",
76+
nums: []int{-30, 2, 3},
77+
want: []int{6, -90, -60},
78+
},
79+
{
80+
name: "all negative ones",
81+
nums: []int{-1, -1, -1},
82+
want: []int{1, 1, 1},
83+
},
84+
{
85+
name: "even count of negatives",
86+
nums: []int{-1, -2, -3, -4},
87+
want: []int{-24, -12, -8, -6},
88+
},
89+
}
90+
91+
for _, tt := range tests {
92+
t.Run(tt.name, func(t *testing.T) {
93+
got := productExceptSelf(tt.nums)
94+
if !reflect.DeepEqual(got, tt.want) {
95+
t.Errorf("productExceptSelf(%v) = %v, want %v", tt.nums, got, tt.want)
96+
}
97+
})
98+
}
99+
}
100+
101+
func TestProductExceptSelf_Properties(t *testing.T) {
102+
t.Run("output length equals input length", func(t *testing.T) {
103+
nums := []int{1, 2, 3, 4, 5}
104+
result := productExceptSelf(nums)
105+
if len(result) != len(nums) {
106+
t.Errorf("output length %d != input length %d", len(result), len(nums))
107+
}
108+
})
109+
110+
t.Run("no mutation of input array", func(t *testing.T) {
111+
nums := []int{1, 2, 3, 4}
112+
original := make([]int, len(nums))
113+
copy(original, nums)
114+
productExceptSelf(nums)
115+
if !reflect.DeepEqual(nums, original) {
116+
t.Errorf("input array was mutated: got %v, want %v", nums, original)
117+
}
118+
})
119+
}

0 commit comments

Comments
 (0)