Skip to content

Commit 84e5930

Browse files
authored
Solve 238 - Product of Array Except Self (#11)
1 parent 86d256a commit 84e5930

File tree

7 files changed

+135
-0
lines changed

7 files changed

+135
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,6 @@ This is a monorepo containing my solutions to LeetCode problems written in vario
1111
- 1 - Two Sum - [Notes](notes/0001_two_sum.md) | [Elixir](elixir/lib/solutions/0001_two_sum/two_sum.ex) | [Ruby](ruby/lib/solutions/0001_two_sum/two_sum.rb)
1212
- 49 - Group Anagrams - [Notes](notes/0049_group_anagrams.md) | [Elixir](elixir/lib/solutions/0049_group_anagrams/group_anagrams.ex) | [Ruby](ruby/lib/solutions/0049_group_anagrams/group_anagrams.rb)
1313
- 217 - Contains Duplicate - [Notes](notes/0217_contains_duplicate.md) | [Elixir](elixir/lib/solutions/0217_contains_duplicate/contains_duplicate.ex) | [Ruby](ruby/lib/solutions/0217_contains_duplicate/contains_duplicate.rb)
14+
- 238 - Product of Array Except Self - [Notes](notes/0238_product_of_array_except_self.md) | [Elixir](elixir/lib/solutions/0238_product_of_array_except_self/product_of_array_except_self.ex) | [Ruby](ruby/lib/solutions/0238_product_of_array_except_self/product_of_array_except_self.rb)
1415
- 242 - Valid Anagram - [Notes](notes/0242_valid_anagram.md) | [Elixir](elixir/lib/solutions/0242_valid_anagram/valid_anagram.ex) | [Ruby](ruby/lib/solutions/0242_valid_anagram/valid_anagram.rb)
1516
- 347 - Top K Frequent Elements - [Notes](notes/0347_top_k_frequent_elements.md) | [Elixir](elixir/lib/solutions/0347_top_k_frequent_elements/top_k_frequent_elements.ex) | [Ruby](ruby/lib/solutions/0347_top_k_frequent_elements/top_k_frequent_elements.rb)
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
defmodule LeetCode.Solutions.ProductOfArrayExceptSelf do
2+
@moduledoc false
3+
4+
@spec call(nums :: [integer]) :: [integer]
5+
def call(nums) do
6+
# This solution doesn't work because it takes too long
7+
# to execute all of the test cases in LeetCode.
8+
# See my notes on this problem for more information.
9+
10+
{prefix_products, _} =
11+
Enum.reduce(nums, {[], 1}, fn num, {products, prefix} ->
12+
{[prefix | products], prefix * num}
13+
end)
14+
15+
nums
16+
|> Enum.reverse()
17+
|> Enum.with_index()
18+
|> Enum.reduce({prefix_products, 1}, fn {num, index}, {products, suffix} ->
19+
{List.update_at(products, index, &(&1 * suffix)), suffix * num}
20+
end)
21+
|> elem(0)
22+
|> Enum.reverse()
23+
end
24+
end
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
defmodule LeetCode.Solutions.ProductOfArrayExceptSelfTest do
2+
use ExUnit.Case, async: true
3+
4+
alias LeetCode.Solutions.ProductOfArrayExceptSelf
5+
6+
test "Case 1 works" do
7+
assert [24, 12, 8, 6] == ProductOfArrayExceptSelf.call([1, 2, 3, 4])
8+
end
9+
10+
test "Case 2 works" do
11+
assert [0, 0, 9, 0, 0] == ProductOfArrayExceptSelf.call([-1, 1, 0, -3, 3])
12+
end
13+
end
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# Product of Array Except Self
2+
3+
**Link to Problem**: https://leetcode.com/problems/product-of-array-except-self
4+
5+
## Solutions
6+
7+
- [Elixir](../elixir/lib/solutions/0238_product_of_array_except_self/product_of_array_except_self.ex)
8+
- [Ruby](../ruby/lib/solutions/0238_product_of_array_except_self/product_of_array_except_self.rb)
9+
10+
## Description
11+
12+
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]`.
13+
14+
The product of any prefix or suffix of `nums` is **guaranteed** to fit in a **32-bit** integer.
15+
16+
You must write an algorithm that runs in `O(n)` time and without using the division operation.
17+
18+
## Examples
19+
20+
### Example 1
21+
22+
```
23+
Input: nums = [1,2,3,4]
24+
Output: [24,12,8,6]
25+
```
26+
27+
### Example 2
28+
29+
```
30+
Input: nums = [-1,1,0,-3,3]
31+
Output: [0,0,9,0,0]
32+
```
33+
34+
## Approach
35+
36+
Loop through `nums` from left to right while keeping track of a `prefix` variable.
37+
38+
During the first loop, assign the current value of `prefix` to the output array.
39+
40+
Next, update `prefix` based on the product of the current `prefix` value and the current iteration of `num`.
41+
42+
Next, we do another loop of `nums` from right to left while keeping track of a `suffix` variable.
43+
44+
We update the current iteration of the output array by multiplying it with the current `suffix`.
45+
46+
Next, we update `suffix` based on the product of the current `suffix` value and current iteration of `nums`.
47+
48+
Once the loop is done, we output the resulting array.
49+
50+
## Thoughts
51+
52+
First of all, there was no way I was going to figure out the solution for this problem on my own.
53+
54+
Next, while the algorithm is easy to do in Ruby, doing it in Elixir is impossible without violating
55+
some of the constraints that the problem has imposed like keeping space complexity to `O(1)`.
56+
57+
Another thing is that my solution for Elixir actually doesn't work. One of the test case for this
58+
problem has an input that is insanely long that my code in Elixir fails to do this before timing out.
59+
60+
My guess is because I've reversed the list so many times and reversing a list is a very expensive
61+
operation since lists in Elixir are linked list and not actual arrays.

ruby/.rubocop.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,6 @@ require:
44

55
AllCops:
66
NewCops: enable
7+
8+
Metrics/MethodLength:
9+
Enabled: false
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# frozen_string_literal: true
2+
3+
def product_except_self(nums)
4+
prefix = 1
5+
suffix = 1
6+
product = []
7+
8+
nums.each do |num|
9+
product << prefix
10+
prefix *= num
11+
end
12+
13+
(nums.length - 1).downto(0) do |index|
14+
product[index] *= suffix
15+
suffix *= nums[index]
16+
end
17+
18+
product
19+
end
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# frozen_string_literal: true
2+
3+
require 'test_helper'
4+
require_relative '../../../lib/solutions/0238_product_of_array_except_self/product_of_array_except_self'
5+
6+
class ProductOfArrayExceptSelfTest < Minitest::Test
7+
def test_case_1_works
8+
assert_equal [24, 12, 8, 6], product_except_self([1, 2, 3, 4])
9+
end
10+
11+
def test_case_2_works
12+
assert_equal [0, 0, 9, 0, 0], product_except_self([-1, 1, 0, -3, 3])
13+
end
14+
end

0 commit comments

Comments
 (0)