From ab45e53e4a90ce1890f7ba3924c03fa01369a190 Mon Sep 17 00:00:00 2001 From: Austin Gebauer Date: Fri, 24 Nov 2023 12:46:00 -0800 Subject: [PATCH 01/12] merge_sorted_array_88: additional solution --- go.sum | 2 +- merge_sorted_array_88/solution.go | 21 ++++++++++++++++++++- merge_sorted_array_88/solution_test.go | 5 +++-- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/go.sum b/go.sum index f520132..331fa69 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,3 @@ -github.com/austingebauer/leetcode v0.0.0-20200305172347-4c676793876f h1:A/S3S1hRavbbUCRkWer4VGKpMhavNVroN1on5YFUH2I= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -6,6 +5,7 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/merge_sorted_array_88/solution.go b/merge_sorted_array_88/solution.go index 03aa1cd..3a21d7a 100644 --- a/merge_sorted_array_88/solution.go +++ b/merge_sorted_array_88/solution.go @@ -1,5 +1,24 @@ package merge_sorted_array_88 +// O(m+n) solution +func merge(nums1 []int, m int, nums2 []int, n int) { + if n == 0 { + return + } + + n1, n2, p := m-1, n-1, m+n-1 + for n2 > -1 { + if n1 < 0 || nums2[n2] >= nums1[n1] { + nums1[p] = nums2[n2] + n2-- + } else { + nums1[p] = nums1[n1] + n1-- + } + p-- + } +} + // Note: solution from rotate_string_796 interview that stumped me for a bit. // Wanted to solve without shifting and was tricky. func merge2(nums1 []int, m int, nums2 []int, n int) { @@ -34,7 +53,7 @@ func merge2(nums1 []int, m int, nums2 []int, n int) { } // Note: original solution with array shifting -func merge(nums1 []int, m int, nums2 []int, n int) { +func merge0(nums1 []int, m int, nums2 []int, n int) { slot := 0 // for each in nums2, insert into nums1 diff --git a/merge_sorted_array_88/solution_test.go b/merge_sorted_array_88/solution_test.go index ef40589..bb3ffe3 100644 --- a/merge_sorted_array_88/solution_test.go +++ b/merge_sorted_array_88/solution_test.go @@ -1,8 +1,9 @@ package merge_sorted_array_88 import ( - "github.com/stretchr/testify/assert" "testing" + + "github.com/stretchr/testify/assert" ) func Test_merge(t *testing.T) { @@ -68,7 +69,7 @@ func Test_merge(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - // merge2(tt.args.nums1, tt.args.m, tt.args.nums2, tt.args.n) + //merge0(tt.args.nums1, tt.args.m, tt.args.nums2, tt.args.n) merge(tt.args.nums1, tt.args.m, tt.args.nums2, tt.args.n) assert.Equal(t, tt.want, tt.args.nums1) }) From 8ceb9f454e912bb7b340d7b07ee4eebdd8dae1db Mon Sep 17 00:00:00 2001 From: Austin Gebauer Date: Sat, 25 Nov 2023 19:15:43 -0800 Subject: [PATCH 02/12] remove_duplicates_from_sorted_array_26: solved --- .../README.md | 3 ++ .../solution.go | 22 +++++++++++ .../solution_test.go | 37 +++++++++++++++++++ 3 files changed, 62 insertions(+) create mode 100644 remove_duplicates_from_sorted_array_26/README.md create mode 100644 remove_duplicates_from_sorted_array_26/solution.go create mode 100644 remove_duplicates_from_sorted_array_26/solution_test.go diff --git a/remove_duplicates_from_sorted_array_26/README.md b/remove_duplicates_from_sorted_array_26/README.md new file mode 100644 index 0000000..fd02fe4 --- /dev/null +++ b/remove_duplicates_from_sorted_array_26/README.md @@ -0,0 +1,3 @@ +# 26. Remove Duplicates from Sorted Array + +https://leetcode.com/problems/remove-duplicates-from-sorted-array/description/ diff --git a/remove_duplicates_from_sorted_array_26/solution.go b/remove_duplicates_from_sorted_array_26/solution.go new file mode 100644 index 0000000..5c81293 --- /dev/null +++ b/remove_duplicates_from_sorted_array_26/solution.go @@ -0,0 +1,22 @@ +package remove_duplicates_from_sorted_array_26 + +func removeDuplicates(nums []int) int { + i, j, u := 0, 0, 1 + for j < len(nums)-1 { + j = i + for j < len(nums)-1 && nums[i] == nums[j] { + j++ + } + if nums[i] != nums[j] { + u++ + } + + for k := j - 1; k > i; k-- { + nums[k] = nums[j] + } + + i++ + } + + return u +} diff --git a/remove_duplicates_from_sorted_array_26/solution_test.go b/remove_duplicates_from_sorted_array_26/solution_test.go new file mode 100644 index 0000000..617bd27 --- /dev/null +++ b/remove_duplicates_from_sorted_array_26/solution_test.go @@ -0,0 +1,37 @@ +package remove_duplicates_from_sorted_array_26 + +import "testing" + +func Test_removeDuplicates(t *testing.T) { + type args struct { + nums []int + } + tests := []struct { + name string + args args + want int + }{ + { + name: "remove duplicates", + args: args{nums: []int{1, 1, 2}}, + want: 2, + }, + { + name: "remove duplicates", + args: args{nums: []int{1, 1}}, + want: 1, + }, + { + name: "remove duplicates", + args: args{nums: []int{0, 0, 1, 1, 1, 2, 2, 3, 3, 4}}, + want: 5, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := removeDuplicates(tt.args.nums); got != tt.want { + t.Errorf("removeDuplicates() = %v, want %v", got, tt.want) + } + }) + } +} From c754ccbab40e8ec470dbe58dc5eda0ab89d8ef81 Mon Sep 17 00:00:00 2001 From: Austin Gebauer Date: Tue, 6 Aug 2024 07:32:13 -0700 Subject: [PATCH 03/12] merge_strings_alternately_1768: solved --- merge_strings_alternately_1768/README.md | 3 ++ merge_strings_alternately_1768/solution.go | 27 ++++++++++ .../solution_test.go | 49 +++++++++++++++++++ 3 files changed, 79 insertions(+) create mode 100644 merge_strings_alternately_1768/README.md create mode 100644 merge_strings_alternately_1768/solution.go create mode 100644 merge_strings_alternately_1768/solution_test.go diff --git a/merge_strings_alternately_1768/README.md b/merge_strings_alternately_1768/README.md new file mode 100644 index 0000000..b146768 --- /dev/null +++ b/merge_strings_alternately_1768/README.md @@ -0,0 +1,3 @@ +# 1768. Merge Strings Alternately + +https://leetcode.com/problems/merge-strings-alternately diff --git a/merge_strings_alternately_1768/solution.go b/merge_strings_alternately_1768/solution.go new file mode 100644 index 0000000..3b33942 --- /dev/null +++ b/merge_strings_alternately_1768/solution.go @@ -0,0 +1,27 @@ +package add_two_numbers_2 + +func mergeAlternately(word1 string, word2 string) string { + var ( + res string + i, j, k int + ) + + for i+j < len(word1)+len(word2) { + if i < len(word1) && k%2 == 0 { + res += string(word1[i]) + i++ + if j < len(word2) { + k++ + } + } + if j < len(word2) && k%2 == 1 { + res += string(word2[j]) + j++ + if i < len(word1) { + k++ + } + } + } + + return res +} diff --git a/merge_strings_alternately_1768/solution_test.go b/merge_strings_alternately_1768/solution_test.go new file mode 100644 index 0000000..3cb7dc3 --- /dev/null +++ b/merge_strings_alternately_1768/solution_test.go @@ -0,0 +1,49 @@ +package add_two_numbers_2 + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func Test_mergeAlternately(t *testing.T) { + type args struct { + word1 string + word2 string + } + tests := []struct { + name string + args args + want string + }{ + { + name: "same length", + args: args{ + word1: "abc", + word2: "pqr", + }, + want: "apbqcr", + }, + { + name: "different length 1", + args: args{ + word1: "ab", + word2: "pqrs", + }, + want: "apbqrs", + }, + { + name: "different length 2", + args: args{ + word1: "abcd", + word2: "pq", + }, + want: "apbqcd", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equalf(t, tt.want, mergeAlternately(tt.args.word1, tt.args.word2), "mergeAlternately(%v, %v)", tt.args.word1, tt.args.word2) + }) + } +} From 527b11868f6af34175d036dfc7faf9ef5abca5b5 Mon Sep 17 00:00:00 2001 From: Austin Gebauer Date: Tue, 6 Aug 2024 08:08:14 -0700 Subject: [PATCH 04/12] move_zeroes_283: solved 2 --- move_zeroes_283/solution.go | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/move_zeroes_283/solution.go b/move_zeroes_283/solution.go index a6693ba..df49546 100644 --- a/move_zeroes_283/solution.go +++ b/move_zeroes_283/solution.go @@ -1,9 +1,9 @@ package move_zeroes_283 -// Note: tricky problem! // Ex: [1,0,0,3,12] -// i -// p +// +// i +// p func moveZeroes(nums []int) { placement := 0 for i := 0; i < len(nums); i++ { @@ -15,3 +15,17 @@ func moveZeroes(nums []int) { } } } + +func moveZeroes2(nums []int) { + i, j := 0, 1 + for j < len(nums) { + if nums[i] != 0 { + i++ + } + if nums[i] == 0 && nums[j] != 0 { + nums[i], nums[j] = nums[j], nums[i] + i++ + } + j++ + } +} From 4c8dc1bafca8ec91cd4e58d0ae1032ab2072b95f Mon Sep 17 00:00:00 2001 From: Austin Gebauer Date: Wed, 7 Aug 2024 08:14:56 -0700 Subject: [PATCH 05/12] maximum_average_subarray_i_643: solved --- maximum_average_subarray_i_643/README.md | 3 ++ maximum_average_subarray_i_643/solution.go | 24 +++++++++++ .../solution_test.go | 41 +++++++++++++++++++ merge_strings_alternately_1768/solution.go | 2 +- .../solution_test.go | 2 +- move_zeroes_283/solution_test.go | 3 +- 6 files changed, 72 insertions(+), 3 deletions(-) create mode 100644 maximum_average_subarray_i_643/README.md create mode 100644 maximum_average_subarray_i_643/solution.go create mode 100644 maximum_average_subarray_i_643/solution_test.go diff --git a/maximum_average_subarray_i_643/README.md b/maximum_average_subarray_i_643/README.md new file mode 100644 index 0000000..3f0b3d8 --- /dev/null +++ b/maximum_average_subarray_i_643/README.md @@ -0,0 +1,3 @@ +# 643. Maximum Average Subarray I + +https://leetcode.com/problems/maximum-average-subarray-i/description/ diff --git a/maximum_average_subarray_i_643/solution.go b/maximum_average_subarray_i_643/solution.go new file mode 100644 index 0000000..0141fa8 --- /dev/null +++ b/maximum_average_subarray_i_643/solution.go @@ -0,0 +1,24 @@ +package maximum_average_subarray_i_643 + +import "math" + +func findMaxAverage(nums []int, k int) float64 { + start := 0 + end := k - 1 + sum := 0.0 + + for i := start; i <= end; i++ { + sum += float64(nums[i]) + } + + maxAvg := sum / float64(k) + for end < len(nums)-1 { + sum -= float64(nums[start]) + sum += float64(nums[end+1]) + maxAvg = math.Max(maxAvg, sum/float64(k)) + start++ + end++ + } + + return maxAvg +} diff --git a/maximum_average_subarray_i_643/solution_test.go b/maximum_average_subarray_i_643/solution_test.go new file mode 100644 index 0000000..26b9643 --- /dev/null +++ b/maximum_average_subarray_i_643/solution_test.go @@ -0,0 +1,41 @@ +package maximum_average_subarray_i_643 + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func Test_findMaxAverage(t *testing.T) { + type args struct { + nums []int + k int + } + tests := []struct { + name string + args args + want float64 + }{ + { + name: "many numbers", + args: args{ + nums: []int{1, 12, -5, -6, 50, 3}, + k: 4, + }, + want: 12.75000, + }, + { + name: "single number", + args: args{ + nums: []int{5}, + k: 1, + }, + want: 5.00000, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equal(t, tt.want, findMaxAverage(tt.args.nums, tt.args.k)) + }) + } +} diff --git a/merge_strings_alternately_1768/solution.go b/merge_strings_alternately_1768/solution.go index 3b33942..8a53947 100644 --- a/merge_strings_alternately_1768/solution.go +++ b/merge_strings_alternately_1768/solution.go @@ -1,4 +1,4 @@ -package add_two_numbers_2 +package merge_strings_alternately_1768 func mergeAlternately(word1 string, word2 string) string { var ( diff --git a/merge_strings_alternately_1768/solution_test.go b/merge_strings_alternately_1768/solution_test.go index 3cb7dc3..76688c3 100644 --- a/merge_strings_alternately_1768/solution_test.go +++ b/merge_strings_alternately_1768/solution_test.go @@ -1,4 +1,4 @@ -package add_two_numbers_2 +package merge_strings_alternately_1768 import ( "testing" diff --git a/move_zeroes_283/solution_test.go b/move_zeroes_283/solution_test.go index bb61e9d..18f72ac 100644 --- a/move_zeroes_283/solution_test.go +++ b/move_zeroes_283/solution_test.go @@ -1,8 +1,9 @@ package move_zeroes_283 import ( - "github.com/stretchr/testify/assert" "testing" + + "github.com/stretchr/testify/assert" ) func Test_moveZeroes(t *testing.T) { From 69e1354a37c117f5839e6ccaa515ea703a32139d Mon Sep 17 00:00:00 2001 From: Austin Gebauer Date: Thu, 8 Aug 2024 08:23:55 -0700 Subject: [PATCH 06/12] find_the_highest_altitude_1732: solved --- find_the_highest_altitude_1732/README.md | 3 ++ find_the_highest_altitude_1732/solution.go | 26 +++++++++++++++ .../solution_test.go | 32 +++++++++++++++++++ template/README.md | 3 ++ template/solution.go | 1 + template/solution_test.go | 1 + 6 files changed, 66 insertions(+) create mode 100644 find_the_highest_altitude_1732/README.md create mode 100644 find_the_highest_altitude_1732/solution.go create mode 100644 find_the_highest_altitude_1732/solution_test.go create mode 100644 template/README.md create mode 100644 template/solution.go create mode 100644 template/solution_test.go diff --git a/find_the_highest_altitude_1732/README.md b/find_the_highest_altitude_1732/README.md new file mode 100644 index 0000000..e752828 --- /dev/null +++ b/find_the_highest_altitude_1732/README.md @@ -0,0 +1,3 @@ +# Number. Title + +TODO: link to problem \ No newline at end of file diff --git a/find_the_highest_altitude_1732/solution.go b/find_the_highest_altitude_1732/solution.go new file mode 100644 index 0000000..90ed24b --- /dev/null +++ b/find_the_highest_altitude_1732/solution.go @@ -0,0 +1,26 @@ +package template + +import "math" + +// -4 -3 -2 -1 4 3 2 +// +// ^ +// +// -4 -7 -9 -10 -6 -3 -1 +func largestAltitude(gain []int) int { + prefixSums := make([]int, len(gain)) + for i, g := range gain { + toAdd := 0 + if i > 0 { + toAdd = prefixSums[i-1] + } + prefixSums[i] = toAdd + g + } + + // catch is that zero starting point could be the highest altitude + max := 0 + for _, s := range prefixSums { + max = int(math.Max(float64(max), float64(s))) + } + return max +} diff --git a/find_the_highest_altitude_1732/solution_test.go b/find_the_highest_altitude_1732/solution_test.go new file mode 100644 index 0000000..b753c24 --- /dev/null +++ b/find_the_highest_altitude_1732/solution_test.go @@ -0,0 +1,32 @@ +package template + +import "testing" + +func Test_largestAltitude(t *testing.T) { + type args struct { + gain []int + } + tests := []struct { + name string + args args + want int + }{ + { + name: "1", + args: args{gain: []int{-5, 1, 5, 0, -7}}, + want: 1, + }, + { + name: "2", + args: args{gain: []int{-4, -3, -2, -1, 4, 3, 2}}, + want: 0, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := largestAltitude(tt.args.gain); got != tt.want { + t.Errorf("largestAltitude() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/template/README.md b/template/README.md new file mode 100644 index 0000000..c96daf2 --- /dev/null +++ b/template/README.md @@ -0,0 +1,3 @@ +# Number. Title + +https://leetcode.com/problems/find-the-highest-altitude/description/ \ No newline at end of file diff --git a/template/solution.go b/template/solution.go new file mode 100644 index 0000000..38cdfe4 --- /dev/null +++ b/template/solution.go @@ -0,0 +1 @@ +package template diff --git a/template/solution_test.go b/template/solution_test.go new file mode 100644 index 0000000..38cdfe4 --- /dev/null +++ b/template/solution_test.go @@ -0,0 +1 @@ +package template From 8d441d4227287d7ab9be418373fdef09c65067fe Mon Sep 17 00:00:00 2001 From: Austin Gebauer Date: Thu, 8 Aug 2024 08:24:15 -0700 Subject: [PATCH 07/12] find_the_highest_altitude_1732: fix package name --- find_the_highest_altitude_1732/solution.go | 2 +- find_the_highest_altitude_1732/solution_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/find_the_highest_altitude_1732/solution.go b/find_the_highest_altitude_1732/solution.go index 90ed24b..3922906 100644 --- a/find_the_highest_altitude_1732/solution.go +++ b/find_the_highest_altitude_1732/solution.go @@ -1,4 +1,4 @@ -package template +package find_the_highest_altitude_1732 import "math" diff --git a/find_the_highest_altitude_1732/solution_test.go b/find_the_highest_altitude_1732/solution_test.go index b753c24..14341a1 100644 --- a/find_the_highest_altitude_1732/solution_test.go +++ b/find_the_highest_altitude_1732/solution_test.go @@ -1,4 +1,4 @@ -package template +package find_the_highest_altitude_1732 import "testing" From da0ff4c2e559f366da4f9f53f65cd9937223e44e Mon Sep 17 00:00:00 2001 From: Austin Gebauer Date: Thu, 8 Aug 2024 08:24:45 -0700 Subject: [PATCH 08/12] find_the_highest_altitude_1732: rename var --- find_the_highest_altitude_1732/solution.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/find_the_highest_altitude_1732/solution.go b/find_the_highest_altitude_1732/solution.go index 3922906..a95cea0 100644 --- a/find_the_highest_altitude_1732/solution.go +++ b/find_the_highest_altitude_1732/solution.go @@ -18,9 +18,9 @@ func largestAltitude(gain []int) int { } // catch is that zero starting point could be the highest altitude - max := 0 + highest := 0 for _, s := range prefixSums { - max = int(math.Max(float64(max), float64(s))) + highest = int(math.Max(float64(highest), float64(s))) } - return max + return highest } From 9c87db3b0e3c7042f731e6891498ded60c2bf1a7 Mon Sep 17 00:00:00 2001 From: Austin Gebauer Date: Sun, 11 Aug 2024 16:27:04 -0700 Subject: [PATCH 09/12] find_the_difference_of_two_arrays_2215: solved --- .../README.md | 3 ++ .../solution.go | 29 +++++++++++++ .../solution_test.go | 43 +++++++++++++++++++ go.mod | 8 +++- 4 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 find_the_difference_of_two_arrays_2215/README.md create mode 100644 find_the_difference_of_two_arrays_2215/solution.go create mode 100644 find_the_difference_of_two_arrays_2215/solution_test.go diff --git a/find_the_difference_of_two_arrays_2215/README.md b/find_the_difference_of_two_arrays_2215/README.md new file mode 100644 index 0000000..a5742c6 --- /dev/null +++ b/find_the_difference_of_two_arrays_2215/README.md @@ -0,0 +1,3 @@ +# 2215. Find the Difference of Two Arrays + +https://leetcode.com/problems/find-the-difference-of-two-arrays/description/ \ No newline at end of file diff --git a/find_the_difference_of_two_arrays_2215/solution.go b/find_the_difference_of_two_arrays_2215/solution.go new file mode 100644 index 0000000..51830a9 --- /dev/null +++ b/find_the_difference_of_two_arrays_2215/solution.go @@ -0,0 +1,29 @@ +package find_the_difference_of_two_arrays_2215 + +func findDifference(nums1 []int, nums2 []int) [][]int { + set1 := sliceToSet(nums1) + set2 := sliceToSet(nums2) + diff := make([][]int, 2) + diff[0] = setDifference(set1, set2) + diff[1] = setDifference(set2, set1) + return diff +} + +func setDifference(s1, s2 map[int]struct{}) []int { + var res []int + for k := range s1 { + if _, ok := s2[k]; !ok { + res = append(res, k) + } + } + + return res +} + +func sliceToSet(a []int) map[int]struct{} { + s := make(map[int]struct{}) + for _, v := range a { + s[v] = struct{}{} + } + return s +} diff --git a/find_the_difference_of_two_arrays_2215/solution_test.go b/find_the_difference_of_two_arrays_2215/solution_test.go new file mode 100644 index 0000000..e61b459 --- /dev/null +++ b/find_the_difference_of_two_arrays_2215/solution_test.go @@ -0,0 +1,43 @@ +package find_the_difference_of_two_arrays_2215 + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func Test_findDifference(t *testing.T) { + type args struct { + nums1 []int + nums2 []int + } + tests := []struct { + name string + args args + want [][]int + }{ + { + name: "1", + args: args{ + nums1: []int{1, 2, 3}, + nums2: []int{2, 4, 6}, + }, + want: [][]int{{1, 3}, {4, 6}}, + }, + { + name: "2", + args: args{ + nums1: []int{1, 2, 3, 3}, + nums2: []int{1, 1, 2, 2}, + }, + want: [][]int{{3}, nil}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := findDifference(tt.args.nums1, tt.args.nums2) + assert.ElementsMatch(t, tt.want[0], got[0]) + assert.ElementsMatch(t, tt.want[1], got[1]) + }) + } +} diff --git a/go.mod b/go.mod index 24d7208..ffa2aa9 100644 --- a/go.mod +++ b/go.mod @@ -1,5 +1,11 @@ module github.com/austingebauer/go-leetcode -go 1.14 +go 1.22.6 require github.com/stretchr/testify v1.5.1 + +require ( + github.com/davecgh/go-spew v1.1.0 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + gopkg.in/yaml.v2 v2.2.2 // indirect +) From 1c1328ff20a4810529edfabbf2a5567300ec9bd0 Mon Sep 17 00:00:00 2001 From: Austin Gebauer Date: Tue, 7 Jan 2025 20:59:10 -0800 Subject: [PATCH 10/12] flatten_nested_list_iterator_341: solved --- flatten_nested_list_iterator_341/solution.go | 133 ++++++++++++++++++ .../solution_test.go | 66 +++++++++ 2 files changed, 199 insertions(+) create mode 100644 flatten_nested_list_iterator_341/solution.go create mode 100644 flatten_nested_list_iterator_341/solution_test.go diff --git a/flatten_nested_list_iterator_341/solution.go b/flatten_nested_list_iterator_341/solution.go new file mode 100644 index 0000000..466a445 --- /dev/null +++ b/flatten_nested_list_iterator_341/solution.go @@ -0,0 +1,133 @@ +package flatten_nested_list_iterator_341 + +/** + * // This is the interface that allows for creating nested lists. + * // You should not implement it, or speculate about its implementation + * type NestedInteger struct { + * } + * + * // Return true if this NestedInteger holds a single integer, rather than a nested list. + * func (this NestedInteger) IsInteger() bool {} + * + * // Return the single integer that this NestedInteger holds, if it holds a single integer + * // The result is undefined if this NestedInteger holds a nested list + * // So before calling this method, you should have a check + * func (this NestedInteger) GetInteger() int {} + * + * // Set this NestedInteger to hold a single integer. + * func (n *NestedInteger) SetInteger(value int) {} + * + * // Set this NestedInteger to hold a nested list and adds a nested integer to it. + * func (this *NestedInteger) Add(elem NestedInteger) {} + * + * // Return the nested list that this NestedInteger holds, if it holds a nested list + * // The list length is zero if this NestedInteger holds a single integer + * // You can access NestedInteger's List element directly if you want to modify it + * func (this NestedInteger) GetList() []*NestedInteger {} + */ + +type NestedInteger struct { + value any + isInt bool +} + +func NewNestedInteger(value any) *NestedInteger { + var isInt bool + if _, ok := value.(int); ok { + isInt = true + } + return &NestedInteger{ + value: value, + isInt: isInt, + } +} + +func (this NestedInteger) IsInteger() bool { + return this.isInt +} +func (this NestedInteger) GetInteger() int { + v := this.value.(int) + return v +} +func (this NestedInteger) GetList() []*NestedInteger { + v := this.value.([]*NestedInteger) + return v +} + +type ListIndex struct { + Idx int + List []*NestedInteger +} + +type Stack struct { + items []*ListIndex +} + +func (s *Stack) Push(v *ListIndex) { + s.items = append(s.items, v) +} + +func (s *Stack) Pop() *ListIndex { + if len(s.items) <= 0 { + return nil + } + + val := s.items[len(s.items)-1] + s.items = s.items[:len(s.items)-1] + return val +} + +func (s *Stack) Peek() *ListIndex { + if len(s.items) <= 0 { + return nil + } + + return s.items[len(s.items)-1] +} + +func (s *Stack) IsEmpty() bool { + return len(s.items) == 0 +} + +type NestedIterator struct { + stack *Stack +} + +func Constructor(nestedList []*NestedInteger) *NestedIterator { + stack := new(Stack) + stack.Push(&ListIndex{ + Idx: 0, + List: nestedList, + }) + + return &NestedIterator{ + stack: stack, + } +} + +func (this *NestedIterator) Next() int { + current := this.stack.Peek() + for !current.List[current.Idx].IsInteger() { + next := &ListIndex{ + Idx: 0, + List: current.List[current.Idx].GetList(), + } + this.stack.Push(next) + + current.Idx++ + current = next + } + + value := current.List[current.Idx].GetInteger() + current.Idx++ + + if current.Idx == len(current.List) { + this.stack.Pop() + } + + return value +} + +func (this *NestedIterator) HasNext() bool { + return !this.stack.IsEmpty() && this.stack.Peek().Idx != len(this.stack.Peek().List) +} diff --git a/flatten_nested_list_iterator_341/solution_test.go b/flatten_nested_list_iterator_341/solution_test.go new file mode 100644 index 0000000..f7d6463 --- /dev/null +++ b/flatten_nested_list_iterator_341/solution_test.go @@ -0,0 +1,66 @@ +package flatten_nested_list_iterator_341 + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestIterator(t *testing.T) { + type args struct { + list []*NestedInteger + } + + tests := []struct { + name string + args args + want []int + }{ + { + name: "1", + args: args{ + // [[1,1],2,[1,1]] + list: []*NestedInteger{ + NewNestedInteger([]*NestedInteger{ + NewNestedInteger(1), + NewNestedInteger(1), + }), + NewNestedInteger(2), + NewNestedInteger([]*NestedInteger{ + NewNestedInteger(1), + NewNestedInteger(1), + }), + }, + }, + want: []int{1, 1, 2, 1, 1}, + }, + { + name: "1", + args: args{ + // [1,[4,[6]]] + list: []*NestedInteger{ + NewNestedInteger(1), + NewNestedInteger([]*NestedInteger{ + NewNestedInteger(4), + NewNestedInteger([]*NestedInteger{ + NewNestedInteger(6), + }), + }), + }, + }, + want: []int{1, 4, 6}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var got []int + + itr := Constructor(tt.args.list) + for itr.HasNext() { + got = append(got, itr.Next()) + } + assert.Equal(t, tt.want, got) + }) + } +} From 341ad88727fa664ee81c5ee396158fc202b19459 Mon Sep 17 00:00:00 2001 From: Austin Gebauer Date: Tue, 7 Jan 2025 21:02:23 -0800 Subject: [PATCH 11/12] design_sql_2408: solved --- design_sql_2408/README.md | 3 ++ design_sql_2408/solution.go | 85 +++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+) create mode 100644 design_sql_2408/README.md create mode 100644 design_sql_2408/solution.go diff --git a/design_sql_2408/README.md b/design_sql_2408/README.md new file mode 100644 index 0000000..5951c0d --- /dev/null +++ b/design_sql_2408/README.md @@ -0,0 +1,3 @@ +# 2408. Design SQL + +https://leetcode.com/problems/design-sql/description/ \ No newline at end of file diff --git a/design_sql_2408/solution.go b/design_sql_2408/solution.go new file mode 100644 index 0000000..c13a4f4 --- /dev/null +++ b/design_sql_2408/solution.go @@ -0,0 +1,85 @@ +package design_sql_2408 + +import ( + "fmt" + "strings" +) + +type table struct { + idInc int + colCount int + rows map[int][]string +} + +type SQL struct { + tables map[string]*table +} + +func Constructor(names []string, columns []int) SQL { + sql := SQL{ + tables: make(map[string]*table), + } + for i, name := range names { + colCount := columns[i] + sql.tables[name] = &table{ + idInc: 0, + colCount: colCount, + rows: make(map[int][]string), + } + } + + return sql +} + +func (q *SQL) Ins(name string, row []string) bool { + table, ok := q.tables[name] + if !ok || len(row) != table.colCount { + return false + } + + table.idInc++ + table.rows[table.idInc] = row + return true +} + +func (q *SQL) Rmv(name string, rowId int) { + table, ok := q.tables[name] + if !ok { + return + } + + // deletes are idempotent, no need to check if it exists or not + delete(table.rows, rowId) +} + +func (q *SQL) Sel(name string, rowId int, columnId int) string { + table, ok := q.tables[name] + if !ok { + return "" + } + + row, ok := table.rows[rowId] + if !ok { + return "" + } + + if columnId < 1 || columnId > len(row) { + return "" + } + + return row[columnId-1] +} + +func (q *SQL) Exp(name string) []string { + table, ok := q.tables[name] + if !ok { + return []string{} + } + + rows := make([]string, 0, len(table.rows)) + for id, row := range table.rows { + rows = append(rows, fmt.Sprintf("%d,%s", id, strings.Join(row, ","))) + } + + return rows +} From 0c6e04f8ece193d3b2c78c308bcfa39f4cf61ac2 Mon Sep 17 00:00:00 2001 From: Austin Gebauer Date: Tue, 7 Jan 2025 21:14:45 -0800 Subject: [PATCH 12/12] time_based_key_value_store_981: solved --- time_based_key_value_store_981/README.md | 3 + time_based_key_value_store_981/solution.go | 61 +++++++++++++++++++ .../solution_test.go | 18 ++++++ 3 files changed, 82 insertions(+) create mode 100644 time_based_key_value_store_981/README.md create mode 100644 time_based_key_value_store_981/solution.go create mode 100644 time_based_key_value_store_981/solution_test.go diff --git a/time_based_key_value_store_981/README.md b/time_based_key_value_store_981/README.md new file mode 100644 index 0000000..b54e661 --- /dev/null +++ b/time_based_key_value_store_981/README.md @@ -0,0 +1,3 @@ +# 981. Time Based Key-Value Store + +https://leetcode.com/problems/time-based-key-value-store/description/ \ No newline at end of file diff --git a/time_based_key_value_store_981/solution.go b/time_based_key_value_store_981/solution.go new file mode 100644 index 0000000..7c99dc8 --- /dev/null +++ b/time_based_key_value_store_981/solution.go @@ -0,0 +1,61 @@ +package time_based_key_value_store_981 + +import "sort" + +type entry struct { + value string + timestamp int +} + +type TimeMap struct { + m map[string][]*entry +} + +func Constructor() TimeMap { + return TimeMap{ + m: make(map[string][]*entry), + } +} + +func (m *TimeMap) Set(key string, value string, timestamp int) { + entries, ok := m.m[key] + if !ok { + entries = make([]*entry, 0) + } + + // perform a binary search for the sorted insertion point (timestamp asc) + index := sort.Search(len(entries), func(i int) bool { + return entries[i].timestamp > timestamp + }) + + // insert the new entry at the sorted insertion point + newEntry := &entry{value: value, timestamp: timestamp} + if index == len(entries) { + entries = append(entries, newEntry) + } else { + // perform a copy-shift insert + entries = append(entries, nil) // make space + copy(entries[index+1:], entries[index:]) + entries[index] = newEntry + } + + m.m[key] = entries +} + +func (m *TimeMap) Get(key string, timestamp int) string { + entries, ok := m.m[key] + if !ok { + return "" + } + + // Find the first entry where the timestamp is greater. This means + // the one right behind it is our entry to return. + index := sort.Search(len(entries), func(i int) bool { + return entries[i].timestamp > timestamp + }) + if index == 0 { + return "" + } + + return entries[index-1].value +} diff --git a/time_based_key_value_store_981/solution_test.go b/time_based_key_value_store_981/solution_test.go new file mode 100644 index 0000000..1b141fe --- /dev/null +++ b/time_based_key_value_store_981/solution_test.go @@ -0,0 +1,18 @@ +package time_based_key_value_store_981 + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestKV(t *testing.T) { + kv := Constructor() + kv.Set("foo", "bar", 1) + kv.Set("foo", "baz", 4) + assert.Equal(t, "", kv.Get("foo", 0)) + assert.Equal(t, "bar", kv.Get("foo", 3)) + assert.Equal(t, "bar", kv.Get("foo", 2)) + assert.Equal(t, "baz", kv.Get("foo", 4)) + assert.Equal(t, "baz", kv.Get("foo", 6)) +}