From e35b5ba5851c65cb6daa37ea0da5e5ed0a1d27f0 Mon Sep 17 00:00:00 2001 From: javy99 Date: Wed, 4 Jun 2025 20:53:38 +0200 Subject: [PATCH] solution for longest consecutive sequence --- .../solution.go | 141 ++++++++++++++++++ .../solution_test.go | 56 +++++++ 2 files changed, 197 insertions(+) create mode 100644 1_arrays_and_hashing/9_longest_consecutive_sequence/solution.go create mode 100644 1_arrays_and_hashing/9_longest_consecutive_sequence/solution_test.go diff --git a/1_arrays_and_hashing/9_longest_consecutive_sequence/solution.go b/1_arrays_and_hashing/9_longest_consecutive_sequence/solution.go new file mode 100644 index 0000000..37fb129 --- /dev/null +++ b/1_arrays_and_hashing/9_longest_consecutive_sequence/solution.go @@ -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 +} diff --git a/1_arrays_and_hashing/9_longest_consecutive_sequence/solution_test.go b/1_arrays_and_hashing/9_longest_consecutive_sequence/solution_test.go new file mode 100644 index 0000000..eb0e321 --- /dev/null +++ b/1_arrays_and_hashing/9_longest_consecutive_sequence/solution_test.go @@ -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) + } + }) + } +}