Skip to content

Commit df892d0

Browse files
authored
[Arrays & Hashing][Two Sum] - Implement solution for Leetcode 1 (#8)
1 parent 8437115 commit df892d0

File tree

2 files changed

+136
-0
lines changed

2 files changed

+136
-0
lines changed
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package twosum
2+
3+
import "sort"
4+
5+
// Time complexity: O(n^2)
6+
// Space complexity: O(1)
7+
func TwoSumBruteForce(nums []int, target int) []int {
8+
for i := 0; i < len(nums); i++ {
9+
for j := i + 1; j < len(nums); j++ {
10+
if nums[i]+nums[j] == target {
11+
return []int{i, j}
12+
}
13+
}
14+
}
15+
return nil
16+
}
17+
18+
type Pair struct {
19+
val int
20+
idx int
21+
}
22+
23+
// Time complexity: O(n log n)
24+
// Space complexity: O(n)
25+
func TwoSumSorted(nums []int, target int) []int {
26+
pairs := make([]Pair, len(nums))
27+
for i, v := range nums {
28+
pairs[i] = Pair{val: v, idx: i}
29+
}
30+
sort.Slice(pairs, func(i, j int) bool {
31+
return pairs[i].val < pairs[j].val
32+
})
33+
34+
left, right := 0, len(pairs)-1
35+
for left < right {
36+
sum := pairs[left].val + pairs[right].val
37+
if sum == target {
38+
return []int{pairs[left].idx, pairs[right].idx}
39+
} else if sum < target {
40+
left++
41+
} else {
42+
right--
43+
}
44+
}
45+
return nil
46+
}
47+
48+
// Time complexity: O(n)
49+
// Space complexity: O(n)
50+
func TwoSumMapTwoPass(nums []int, target int) []int {
51+
// First pass: build map
52+
m := make(map[int]int) // value -> index
53+
for i, num := range nums {
54+
m[num] = i
55+
}
56+
57+
// Second pass: check complements
58+
for i, num := range nums {
59+
complement := target - num
60+
if j, ok := m[complement]; ok && i != j {
61+
return []int{i, j}
62+
}
63+
}
64+
return nil
65+
}
66+
67+
// Time complexity: O(n)
68+
// Space complexity: O(n)
69+
func TwoSumMapOnePass(nums []int, target int) []int {
70+
m := make(map[int]int) // value -> index
71+
for i, num := range nums {
72+
complement := target - num
73+
if j, ok := m[complement]; ok {
74+
return []int{j, i}
75+
}
76+
m[num] = i
77+
}
78+
return nil
79+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package twosum
2+
3+
import (
4+
"reflect"
5+
"testing"
6+
)
7+
8+
func TestTwoSum(t *testing.T) {
9+
cases := []struct {
10+
name string
11+
fn func([]int, int) []int
12+
nums []int
13+
target int
14+
expected []int
15+
}{
16+
// TwoSumBruteForce
17+
{"Brute Force - Valid Pair", TwoSumBruteForce, []int{2, 7, 11, 15}, 9, []int{0, 1}},
18+
{"Brute Force - No Pair", TwoSumBruteForce, []int{1, 2, 3}, 7, nil},
19+
{"Brute - Empty", TwoSumBruteForce, []int{}, 0, nil},
20+
{"Brute - Single Element", TwoSumBruteForce, []int{5}, 5, nil},
21+
{"Brute - Negative Numbers", TwoSumBruteForce, []int{-3, 4, 3, 90}, 0, []int{0, 2}},
22+
{"Brute - Duplicates", TwoSumBruteForce, []int{3, 3}, 6, []int{0, 1}},
23+
24+
// Sorting (Two Pointer)
25+
{"Sorted - Valid Pair", TwoSumSorted, []int{2, 7, 11, 15}, 9, []int{0, 1}},
26+
{"Sorted - No Pair", TwoSumSorted, []int{1, 2, 3}, 7, nil},
27+
{"Sorted - Empty", TwoSumSorted, []int{}, 0, nil},
28+
{"Sorted - Single Element", TwoSumSorted, []int{5}, 5, nil},
29+
{"Sorted - Negative Numbers", TwoSumSorted, []int{-3, 4, 3, 90}, 0, []int{0, 2}},
30+
{"Sorted - Duplicates", TwoSumSorted, []int{3, 3}, 6, []int{0, 1}},
31+
32+
// Map Two-Pass
33+
{"MapTwoPass - Valid Pair", TwoSumMapTwoPass, []int{2, 7, 11, 15}, 9, []int{0, 1}},
34+
{"MapTwoPass - No Pair", TwoSumMapTwoPass, []int{1, 2, 3}, 7, nil},
35+
{"MapTwoPass - Empty", TwoSumMapTwoPass, []int{}, 0, nil},
36+
{"MapTwoPass - Single", TwoSumMapTwoPass, []int{5}, 5, nil},
37+
{"MapTwoPass - Negative", TwoSumMapTwoPass, []int{-3, 4, 3, 90}, 0, []int{0, 2}},
38+
{"MapTwoPass - Duplicates", TwoSumMapTwoPass, []int{3, 3}, 6, []int{0, 1}},
39+
40+
// Map One-Pass
41+
{"MapOnePass - Valid Pair", TwoSumMapOnePass, []int{2, 7, 11, 15}, 9, []int{0, 1}},
42+
{"MapOnePass - No Pair", TwoSumMapOnePass, []int{1, 2, 3}, 7, nil},
43+
{"MapOnePass - Empty", TwoSumMapOnePass, []int{}, 0, nil},
44+
{"MapOnePass - Single", TwoSumMapOnePass, []int{5}, 5, nil},
45+
{"MapOnePass - Negative", TwoSumMapOnePass, []int{-3, 4, 3, 90}, 0, []int{0, 2}},
46+
{"MapOnePass - Duplicates", TwoSumMapOnePass, []int{3, 3}, 6, []int{0, 1}},
47+
}
48+
49+
for _, c := range cases {
50+
t.Run(c.name, func(t *testing.T) {
51+
got := c.fn(c.nums, c.target)
52+
if !reflect.DeepEqual(got, c.expected) {
53+
t.Errorf("%s failed: expected %v, got %v", c.name, c.expected, got)
54+
}
55+
})
56+
}
57+
}

0 commit comments

Comments
 (0)