Skip to content

Commit 531cbef

Browse files
authored
Solve 1 - Two Sum (#6)
1 parent 423a0af commit 531cbef

File tree

6 files changed

+193
-0
lines changed

6 files changed

+193
-0
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,7 @@
55
[![codecov](https://codecov.io/gh/terenceponce/leetcode/graph/badge.svg?token=i7gC0Uuurl)](https://codecov.io/gh/terenceponce/leetcode)
66

77
This is a monorepo containing my solutions to LeetCode problems written in various languages.
8+
9+
## List of Problems/Solutions
10+
11+
- 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)
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
defmodule LeetCode.Solutions.TwoSum do
2+
@moduledoc false
3+
4+
@spec call(nums :: [integer], target :: integer) :: [integer]
5+
def call(nums, target) do
6+
nums
7+
|> Enum.with_index()
8+
|> Enum.reduce({%{}, []}, fn {num, index}, {map, result} ->
9+
case Map.get(map, target - num) do
10+
nil ->
11+
{Map.put(map, num, index), result}
12+
13+
match ->
14+
{map, [match, index]}
15+
end
16+
end)
17+
|> elem(1)
18+
end
19+
end
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
defmodule LeetCode.Solutions.TwoSumTest do
2+
use ExUnit.Case, async: true
3+
4+
alias LeetCode.Solutions.TwoSum
5+
6+
test "Case 1 works" do
7+
assert TwoSum.call([2, 7, 11, 15], 9) == [0, 1]
8+
end
9+
10+
test "Case 2 works" do
11+
assert TwoSum.call([3, 2, 4], 6) == [1, 2]
12+
end
13+
14+
test "Case 3 works" do
15+
assert TwoSum.call([3, 3], 6) == [0, 1]
16+
end
17+
end

notes/0001_two_sum.md

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
# Two Sum
2+
3+
**Link to Problem**: https://leetcode.com/problems/two-sum
4+
5+
## Solutions
6+
7+
- [Elixir](../elixir/lib/solutions/0001_two_sum/two_sum.ex)
8+
- [Ruby](../ruby/lib/solutions/0001_two_sum/two_sum.rb)
9+
10+
## Description
11+
12+
Given an array of integers `nums` and an integer `target`, return indices of the two numbers such that they add up to `target`.
13+
14+
You may assume that each input would have **exactly one solution**, and you may not use the same element twice.
15+
16+
You can return the answer in any order.
17+
18+
## Examples
19+
20+
### Example 1
21+
22+
```
23+
Input: nums = [2,7,11,15], target = 9
24+
Output: [0,1]
25+
Explanation: Because nums[0] + nums[1] == 9, we return [0, 1].
26+
```
27+
28+
### Example 2
29+
30+
```
31+
Input: nums = [3,2,4], target = 6
32+
Output: [1,2]
33+
```
34+
35+
### Example 3
36+
37+
```
38+
Input: nums = [3,3], target = 6
39+
Output: [0,1]
40+
```
41+
42+
## Solution
43+
44+
This is my first ever LeetCode problem and I usually suck at algorithms, so this took me a long time to get.
45+
46+
For people like me, the first solution I thought of was to iterate through each element in the list,
47+
compare it with all the other elements in the list, and try to add both elements to see if it matches
48+
the target.
49+
50+
Unfortunately, while this does work, it is very slow because you have to go through the list multiple
51+
times in order to get the result.
52+
53+
The optimal solution is to use a Hash Map which makes it possible to get the same answer while only
54+
going through the list once.
55+
56+
Before we dive into the solution itself, I'd like to discuss something else first.
57+
58+
One thing that I had to realize was that there was another way to figure out what elements it would
59+
take to reach the target. The obvious solution is to perform addition on all the elements until we
60+
get a sum that matches the target.
61+
62+
Another way is to do it backwards and perform subtraction instead. We take the current element and
63+
subtract that from the target. From there, we try to figure out if there is an element that matches
64+
the difference.
65+
66+
So how do we do that exactly? By creating a new variable and storing all the value and index of
67+
the current element if it doesn't satisfy the condition to match the target. In this case, we create
68+
a Hash Map (or Map in Elixir) since it allows us to store both value and index.
69+
70+
In the case of Example 2, it would look like this:
71+
72+
```
73+
[3, 2, 4]
74+
^
75+
|
76+
we are here
77+
```
78+
79+
Since the target is `6`, we will do `6 - 3` which is `3`. What we then do is look at our map
80+
to see if there is an element that has `3` as the value.
81+
82+
At this point, our map is still empty, so there won't be any matches. The conclusion for this
83+
element is that we will skip it and go to the next one. However, we will also add this element
84+
into the map before we move to the next one:
85+
86+
```
87+
{3: 0}
88+
```
89+
90+
We put the value as the key, so we can use it for lookups and the index as the value, so we can get it later.
91+
92+
After we stored the first element into the map, we will go to the next element:
93+
94+
```
95+
[3, 2, 4]
96+
^
97+
|
98+
we are here
99+
```
100+
101+
At this point, we will try to do `6 - 2` which is `4`. We then look at the map to see if we
102+
have any matches.
103+
104+
Since we only have `3` inside the map, there won't be any matches. So we repeat what we did
105+
in the previous element which is to add the current element to the map and move on to the next element:
106+
107+
```
108+
{3: 0, 2: 1}
109+
```
110+
111+
Afterwards, we go to the last element:
112+
113+
```
114+
[3, 2, 4]
115+
^
116+
|
117+
we are here
118+
```
119+
120+
Obviously, we will try to do `6 - 4` which will result to `2`. If we do `Map.get(map, target - num)`,
121+
we will get `2` which has the value of `1`. From there, we should now be able to determine that the
122+
indices `[1, 2]` are the answer.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# frozen_string_literal: true
2+
3+
def two_sum(nums, target)
4+
hash = {}
5+
6+
nums.each_with_index do |num, index|
7+
diff = target - num
8+
9+
return [hash[diff], index] if hash[diff]
10+
11+
hash[num] = index
12+
end
13+
end
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# frozen_string_literal: true
2+
3+
require 'test_helper'
4+
require_relative '../../../lib/solutions/0001_two_sum/two_sum'
5+
6+
class TwoSumTest < Minitest::Test
7+
def test_case_1_works
8+
assert_equal [0, 1], two_sum([2, 7, 11, 15], 9)
9+
end
10+
11+
def test_case_2_works
12+
assert_equal [1, 2], two_sum([3, 2, 4], 6)
13+
end
14+
15+
def test_case_3_works
16+
assert_equal [0, 1], two_sum([3, 3], 6)
17+
end
18+
end

0 commit comments

Comments
 (0)