Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
141 changes: 141 additions & 0 deletions 1_arrays_and_hashing/9_longest_consecutive_sequence/solution.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
package longestconsecutivesequence

import (
"sort"
)

// Time complexity: O(n^2)
// Space complexity: O(1)
func LongestConsecutiveBruteForce1(nums []int) int {
maxLen := 0

for _, num := range nums {
current := num
length := 1

for {
found := false
for _, n := range nums {
if n == current+1 {
found = true
current++
length++
break
}
}
if !found {
break
}
}

if length > maxLen {
maxLen = length
}
}

return maxLen
}

// Time complexity: O(n^2)
// Space complexity: O(n)
func LongestConsecutiveBruteForce2(nums []int) int {
res := 0
store := make(map[int]struct{})
for _, num := range nums {
store[num] = struct{}{}
}

for _, num := range nums {
streak, curr := 0, num
for _, ok := store[curr]; ok; _, ok = store[curr] {
streak++
curr++
}
if streak > res {
res = streak
}
}
return res
}

// Time complexity: O(n log n) due to sorting
// Space complexity: O(1) or O(n) depending on sorting algorithm implementation
func LongestConsecutiveSort(nums []int) int {
if len(nums) == 0 {
return 0
}

sort.Ints(nums)
maxLen := 1
currLen := 1

for i := 1; i < len(nums); i++ {
if nums[i] == nums[i-1] {
continue // skip duplicates
}
if nums[i] == nums[i-1]+1 {
currLen++
} else {
currLen = 1
}
if currLen > maxLen {
maxLen = currLen
}
}
return maxLen
}

// Time complexity: O(n)
// Space complexity: O(n)
func LongestConsecutiveHashSet(nums []int) int {
set := make(map[int]bool)
for _, num := range nums {
set[num] = true
}

maxLen := 0
for num := range set {
// Only check starts of sequences
if !set[num-1] {
current := num
length := 1

for set[current+1] {
current++
length++
}
if length > maxLen {
maxLen = length
}
}
}
return maxLen
}

// Time complexity: O(n)
// Space complexity: O(n)
func LongestConsecutiveHashMap(nums []int) int {
if len(nums) == 0 {
return 0
}

lookup := make(map[int]int)
maxLen := 0

for _, num := range nums {
if _, exists := lookup[num]; !exists {
left := lookup[num-1]
right := lookup[num+1]
length := left + right + 1

lookup[num] = length
lookup[num-left] = length
lookup[num+right] = length

if length > maxLen {
maxLen = length
}
}
}
return maxLen
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package longestconsecutivesequence

import "testing"

func TestLongestConsecutive(t *testing.T) {
cases := []struct {
name string
fn func([]int) int
nums []int
expected int
}{
// LongestConsecutiveBruteForce1
{"Brute Force - Example 1", LongestConsecutiveBruteForce1, []int{2, 20, 4, 10, 3, 4, 5}, 4},
{"Brute Force - Example 2", LongestConsecutiveBruteForce1, []int{0, 3, 2, 5, 4, 6, 1, 1}, 7},
{"Brute Force - Empty", LongestConsecutiveBruteForce1, []int{}, 0},
{"Brute Force - Single Element", LongestConsecutiveBruteForce1, []int{42}, 1},
{"Brute Force - All Same", LongestConsecutiveBruteForce1, []int{7, 7, 7}, 1},

// LongestConsecutiveBruteForce2
{"Brute Force - Example 1", LongestConsecutiveBruteForce2, []int{2, 20, 4, 10, 3, 4, 5}, 4},
{"Brute Force - Example 2", LongestConsecutiveBruteForce2, []int{0, 3, 2, 5, 4, 6, 1, 1}, 7},
{"Brute Force - Empty", LongestConsecutiveBruteForce2, []int{}, 0},
{"Brute Force - Single Element", LongestConsecutiveBruteForce2, []int{42}, 1},
{"Brute Force - All Same", LongestConsecutiveBruteForce2, []int{7, 7, 7}, 1},

// LongestConsecutiveSort
{"Sort - Example 1", LongestConsecutiveSort, []int{2, 20, 4, 10, 3, 4, 5}, 4},
{"Sort - Example 2", LongestConsecutiveSort, []int{0, 3, 2, 5, 4, 6, 1, 1}, 7},
{"Sort - Empty", LongestConsecutiveSort, []int{}, 0},
{"Sort - Single Element", LongestConsecutiveSort, []int{42}, 1},
{"Sort - All Same", LongestConsecutiveSort, []int{7, 7, 7}, 1},

// LongestConsecutiveHashSet
{"Hash Set - Example 1", LongestConsecutiveHashSet, []int{2, 20, 4, 10, 3, 4, 5}, 4},
{"Hash Set - Example 2", LongestConsecutiveHashSet, []int{0, 3, 2, 5, 4, 6, 1, 1}, 7},
{"Hash Set - Empty", LongestConsecutiveHashSet, []int{}, 0},
{"Hash Set - Single Element", LongestConsecutiveHashSet, []int{42}, 1},
{"Hash Set - All Same", LongestConsecutiveHashSet, []int{7, 7, 7}, 1},

// LongestConsecutiveHashMap
{"Hash Map - Example 1", LongestConsecutiveHashMap, []int{2, 20, 4, 10, 3, 4, 5}, 4},
{"Hash Map - Example 2", LongestConsecutiveHashMap, []int{0, 3, 2, 5, 4, 6, 1, 1}, 7},
{"Hash Map - Empty", LongestConsecutiveHashMap, []int{}, 0},
{"Hash Map - Single Element", LongestConsecutiveHashMap, []int{42}, 1},
{"Hash Map - All Same", LongestConsecutiveHashMap, []int{7, 7, 7}, 1},
}

for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
got := c.fn(c.nums)
if got != c.expected {
t.Errorf("%s failed: expected %d, got %d", c.name, c.expected, got)
}
})
}
}
Loading