diff --git a/best_time_to_buy_and_sell_stock_121/solution.go b/best_time_to_buy_and_sell_stock_121/solution.go index 3a1b410..54ce7ac 100644 --- a/best_time_to_buy_and_sell_stock_121/solution.go +++ b/best_time_to_buy_and_sell_stock_121/solution.go @@ -2,6 +2,17 @@ package best_time_to_buy_and_sell_stock_121 import "math" +// O(n) time and O(1) space +func maxProfit3(prices []int) int { + var res float64 + var low = math.MaxFloat64 + for _, p := range prices { + res = math.Max(res, float64(p)-low) + low = math.Min(low, float64(p)) + } + return int(res) +} + // O(n) time and O(1) space func maxProfit2(prices []int) int { maxProfit := 0 diff --git a/best_time_to_buy_and_sell_stock_121/solution_test.go b/best_time_to_buy_and_sell_stock_121/solution_test.go index d04fa20..c2063e5 100644 --- a/best_time_to_buy_and_sell_stock_121/solution_test.go +++ b/best_time_to_buy_and_sell_stock_121/solution_test.go @@ -1,44 +1,10 @@ package best_time_to_buy_and_sell_stock_121 import ( - "github.com/stretchr/testify/assert" "testing" -) -func Test_maxProfit2(t *testing.T) { - type args struct { - prices []int - } - tests := []struct { - name string - args args - want int - }{ - { - name: "best time to buy and sell stock", - args: args{ - prices: []int{ - 7, 1, 5, 3, 6, 4, - }, - }, - want: 5, - }, - { - name: "best time to buy and sell stock", - args: args{ - prices: []int{ - 7, 6, 4, 3, 1, - }, - }, - want: 0, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - assert.Equal(t, tt.want, maxProfit2(tt.args.prices)) - }) - } -} + "github.com/stretchr/testify/assert" +) func Test_maxProfit(t *testing.T) { type args struct { @@ -70,6 +36,8 @@ func Test_maxProfit(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { + assert.Equal(t, tt.want, maxProfit3(tt.args.prices)) + assert.Equal(t, tt.want, maxProfit2(tt.args.prices)) assert.Equal(t, tt.want, maxProfit(tt.args.prices)) }) } diff --git a/best_time_to_buy_and_sell_stock_ii_122/README.md b/best_time_to_buy_and_sell_stock_ii_122/README.md new file mode 100644 index 0000000..ea95da7 --- /dev/null +++ b/best_time_to_buy_and_sell_stock_ii_122/README.md @@ -0,0 +1,43 @@ +# 122. Best Time to Buy and Sell Stock II + +https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/ + +## Difficulty: + +Easy + +## Description + +You are given an array prices for which the ith element is the price of a given stock on day i. + +Find the maximum profit you can achieve. You may complete as many transactions as you like (i.e., buy one and sell one share of the stock multiple times). + +Note: You may not engage in multiple transactions simultaneously (i.e., you must sell the stock before you buy again). + +Example 1: +``` +Input: prices = [7,1,5,3,6,4] +Output: 7 +Explanation: Buy on day 2 (price = 1) and sell on day 3 (price = 5), profit = 5-1 = 4. +Then buy on day 4 (price = 3) and sell on day 5 (price = 6), profit = 6-3 = 3. +``` +Example 2: +``` +Input: prices = [1,2,3,4,5] +Output: 4 +Explanation: Buy on day 1 (price = 1) and sell on day 5 (price = 5), profit = 5-1 = 4. +Note that you cannot buy on day 1, buy on day 2 and sell them later, as you are engaging multiple +transactions at the same time. You must sell before buying again. +``` +Example 3: +``` +Input: prices = [7,6,4,3,1] +Output: 0 +Explanation: In this case, no transaction is done, i.e., max profit = 0. +``` + +Constraints: +- 1 <= prices.length <= 3 * 104 +- 0 <= prices[i] <= 104 + +![](https://leetcode.com/media/original_images/122_maxprofit_2.PNG) diff --git a/best_time_to_buy_and_sell_stock_ii_122/solution.go b/best_time_to_buy_and_sell_stock_ii_122/solution.go new file mode 100644 index 0000000..cff49b6 --- /dev/null +++ b/best_time_to_buy_and_sell_stock_ii_122/solution.go @@ -0,0 +1,18 @@ +package best_time_to_buy_and_sell_stock_ii_122 + +// Keep on adding the difference between the consecutive numbers of the slice, +// if the second number is larger than the first one (profit). The image in the +// readme helps to visualize why this works. The problem description could be +// improved, as it doesn't say whether or not selling and buying back on the +// same day is possible. For example, given [2, 5, 8], are we allowed to buy +// at 2, sell at 5, buy back at 5, sell at 8? We can, but the description +// doesn't make that clear. O(n) time and O(1) space. +func maxProfit(prices []int) int { + var res int + for i := 1; i < len(prices); i++ { + if prices[i] > prices[i-1] { + res += prices[i] - prices[i-1] + } + } + return res +} diff --git a/best_time_to_buy_and_sell_stock_ii_122/solution_test.go b/best_time_to_buy_and_sell_stock_ii_122/solution_test.go new file mode 100644 index 0000000..1f5a066 --- /dev/null +++ b/best_time_to_buy_and_sell_stock_ii_122/solution_test.go @@ -0,0 +1,52 @@ +package best_time_to_buy_and_sell_stock_ii_122 + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func Test_maxProfit(t *testing.T) { + type args struct { + prices []int + } + tests := []struct { + name string + args args + want int + }{ + { + name: "best time to buy and sell stock ii", + args: args{ + prices: []int{7, 1, 5, 3, 6, 4}, + }, + want: 7, + }, + { + name: "best time to buy and sell stock ii", + args: args{ + prices: []int{7, 6, 4, 3, 1}, + }, + want: 0, + }, + { + name: "best time to buy and sell stock ii", + args: args{ + prices: []int{2, 7, 1, 8}, + }, + want: 12, + }, + { + name: "best time to buy and sell stock ii", + args: args{ + prices: []int{2, 5, 8}, + }, + want: 6, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equal(t, tt.want, maxProfit(tt.args.prices)) + }) + } +} 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 +} diff --git a/excel_sheet_column_number_171/README.md b/excel_sheet_column_number_171/README.md new file mode 100644 index 0000000..6c03c56 --- /dev/null +++ b/excel_sheet_column_number_171/README.md @@ -0,0 +1,44 @@ +# 171. Excel Sheet Column Number + +https://leetcode.com/problems/excel-sheet-column-number/ + +## Difficulty: + +Easy + +## Description + +Given a column title as appear in an Excel sheet, return its corresponding column number. + +For example: +``` +A -> 1 +B -> 2 +C -> 3 +... +Z -> 26 +AA -> 27 +AB -> 28 +... +``` + +Example 1: +``` +Input: "A" +Output: 1 +``` +Example 2: +``` +Input: "AB" +Output: 28 +``` +Example 3: +``` +Input: "ZY" +Output: 701 +``` + +Constraints: +- 1 <= s.length <= 7 +- s consists only of uppercase English letters. +- s is between "A" and "FXSHRXW". diff --git a/excel_sheet_column_number_171/solution.go b/excel_sheet_column_number_171/solution.go new file mode 100644 index 0000000..2b5a79e --- /dev/null +++ b/excel_sheet_column_number_171/solution.go @@ -0,0 +1,14 @@ +package excel_sheet_column_number_171 + +import "math" + +func titleToNumber(s string) int { + var res int + var exponent float64 + for i := len(s) - 1; i > -1; i-- { + charNum := int(s[i]-'A') + 1 + res += charNum * int(math.Pow(float64(26), exponent)) + exponent++ + } + return res +} diff --git a/excel_sheet_column_number_171/solution_test.go b/excel_sheet_column_number_171/solution_test.go new file mode 100644 index 0000000..6829d28 --- /dev/null +++ b/excel_sheet_column_number_171/solution_test.go @@ -0,0 +1,59 @@ +package excel_sheet_column_number_171 + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func Test_titleToNumber(t *testing.T) { + type args struct { + s string + } + tests := []struct { + name string + args args + want int + }{ + { + name: "excel sheet column number", + args: args{ + s: "A", + }, + want: 1, + }, + { + name: "excel sheet column number", + args: args{ + s: "AB", + }, + want: 28, + }, + { + name: "excel sheet column number", + args: args{ + s: "ZY", + }, + want: 701, + }, + { + name: "excel sheet column number", + args: args{ + s: "YB", + }, + want: 652, + }, + { + name: "excel sheet column number", + args: args{ + s: "AAA", + }, + want: 703, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equal(t, tt.want, titleToNumber(tt.args.s)) + }) + } +} 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/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..a95cea0 --- /dev/null +++ b/find_the_highest_altitude_1732/solution.go @@ -0,0 +1,26 @@ +package find_the_highest_altitude_1732 + +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 + highest := 0 + for _, s := range prefixSums { + highest = int(math.Max(float64(highest), float64(s))) + } + return highest +} 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..14341a1 --- /dev/null +++ b/find_the_highest_altitude_1732/solution_test.go @@ -0,0 +1,32 @@ +package find_the_highest_altitude_1732 + +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/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) + }) + } +} 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 +) 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/intersection_of_two_arrays_ii_350/README.md b/intersection_of_two_arrays_ii_350/README.md new file mode 100644 index 0000000..90b1273 --- /dev/null +++ b/intersection_of_two_arrays_ii_350/README.md @@ -0,0 +1,33 @@ +# 350. Intersection of Two Arrays II + +https://leetcode.com/problems/intersection-of-two-arrays-ii/ + +## Difficulty: + +Easy + +## Description + +Given two arrays, write a function to compute their intersection. + +Example 1: +``` +Input: nums1 = [1,2,2,1], nums2 = [2,2] +Output: [2,2] +``` +Example 2: +``` +Input: nums1 = [4,9,5], nums2 = [9,4,9,8,4] +Output: [4,9] +``` + +Note: + +Each element in the result should appear as many times as it shows in both arrays. +The result can be in any order. + +Follow up: + +- What if the given array is already sorted? How would you optimize your algorithm? +- What if nums1's size is small compared to nums2's size? Which algorithm is better? +- What if elements of nums2 are stored on disk, and the memory is limited such that you cannot load all elements into the memory at once? diff --git a/intersection_of_two_arrays_ii_350/solution.go b/intersection_of_two_arrays_ii_350/solution.go new file mode 100644 index 0000000..9431deb --- /dev/null +++ b/intersection_of_two_arrays_ii_350/solution.go @@ -0,0 +1,18 @@ +package intersection_of_two_arrays_ii_350 + +func intersect(nums1 []int, nums2 []int) []int { + counts := make(map[int]int) + for _, n := range nums1 { + counts[n]++ + } + + res := make([]int, 0) + for _, n := range nums2 { + if v, ok := counts[n]; ok && v > 0 { + res = append(res, n) + counts[n]-- + } + } + + return res +} diff --git a/intersection_of_two_arrays_ii_350/solution_test.go b/intersection_of_two_arrays_ii_350/solution_test.go new file mode 100644 index 0000000..57ab6b3 --- /dev/null +++ b/intersection_of_two_arrays_ii_350/solution_test.go @@ -0,0 +1,41 @@ +package intersection_of_two_arrays_ii_350 + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func Test_intersect(t *testing.T) { + type args struct { + nums1 []int + nums2 []int + } + tests := []struct { + name string + args args + want []int + }{ + { + name: "intersection of two arrays ii", + args: args{ + nums1: []int{1, 2, 2, 1}, + nums2: []int{2, 2}, + }, + want: []int{2, 2}, + }, + { + name: "intersection of two arrays ii", + args: args{ + nums1: []int{4, 9, 5}, + nums2: []int{9, 4, 9, 8, 4}, + }, + want: []int{4, 9}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.ElementsMatch(t, tt.want, intersect(tt.args.nums1, tt.args.nums2)) + }) + } +} diff --git a/intersection_of_two_linked_lists_160/README.md b/intersection_of_two_linked_lists_160/README.md new file mode 100644 index 0000000..790c5fd --- /dev/null +++ b/intersection_of_two_linked_lists_160/README.md @@ -0,0 +1,68 @@ +# 160. Intersection of Two Linked Lists + +https://leetcode.com/problems/intersection-of-two-linked-lists/ + +## Difficulty: + +Easy + +## Description + +Given the heads of two singly linked-lists headA and headB, return the node at which the two lists +intersect. If the two linked lists have no intersection at all, return null. + +For example, the following two linked lists begin to intersect at node c1: + +![](https://assets.leetcode.com/uploads/2021/03/05/160_statement.png) + +It is **guaranteed** that there are no cycles anywhere in the entire linked structure. + +Note that the linked lists must **retain their original structure** after the function returns. + +Example 1: + +![](https://assets.leetcode.com/uploads/2021/03/05/160_example_1_1.png) + +``` +Input: intersectVal = 8, listA = [4,1,8,4,5], listB = [5,6,1,8,4,5], skipA = 2, skipB = 3 +Output: Intersected at '8' +Explanation: The intersected node's value is 8 (note that this must not be 0 if the two lists intersect). +From the head of A, it reads as [4,1,8,4,5]. From the head of B, it reads as [5,6,1,8,4,5]. There +are 2 nodes before the intersected node in A; There are 3 nodes before the intersected node in B. +``` + +Example 2: + +![](https://assets.leetcode.com/uploads/2021/03/05/160_example_2.png) + +``` +Input: intersectVal = 2, listA = [1,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1 +Output: Intersected at '2' +Explanation: The intersected node's value is 2 (note that this must not be 0 if the two lists intersect). +From the head of A, it reads as [1,9,1,2,4]. From the head of B, it reads as [3,2,4]. There are +3 nodes before the intersected node in A; There are 1 node before the intersected node in B. +``` + +Example 3: + +![](https://assets.leetcode.com/uploads/2021/03/05/160_example_3.png) + +``` +Input: intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2 +Output: No intersection +Explanation: From the head of A, it reads as [2,6,4]. From the head of B, it reads as [1,5]. Since +the two lists do not intersect, intersectVal must be 0, while skipA and skipB can be arbitrary values. +Explanation: The two lists do not intersect, so return null. +``` + +Constraints: +- The number of nodes of listA is in the m. +- The number of nodes of listB is in the n. +- 1 <= m, n <= 3 * 104 +- 1 <= Node.val <= 105 +- 1 <= skipA <= m +- 1 <= skipB <= n +- intersectVal is 0 if listA and listB do not intersect. +- intersectVal == listA[skipA + 1] == listB[skipB + 1] if listA and listB intersect. + +Follow up: Could you write a solution that runs in O(n) time and use only O(1) memory? diff --git a/intersection_of_two_linked_lists_160/solution.go b/intersection_of_two_linked_lists_160/solution.go new file mode 100644 index 0000000..ce8bf4e --- /dev/null +++ b/intersection_of_two_linked_lists_160/solution.go @@ -0,0 +1,51 @@ +package intersection_of_two_linked_lists_160 + +import ( + "math" + + . "github.com/austingebauer/go-leetcode/structures" +) + +/** + * Definition for singly-linked list. + * type ListNode struct { + * Val int + * Next *ListNode + * } + */ +func getIntersectionNode(headA, headB *ListNode) *ListNode { + lenA, lenB := length(headA), length(headB) + + // Set itr1 to the list with the greater length + var itr1, itr2 *ListNode + if lenA > lenB { + itr1, itr2 = headA, headB + } else { + itr1, itr2 = headB, headA + } + + // Advance itr1 so that it's in step with itr2 with respect to length + distance := int(math.Abs(float64(lenA - lenB))) + for i := 0; i < distance; i++ { + itr1 = itr1.Next + } + + // Move both pointers forward until an intersection occurs or end of list + for itr1 != nil { + if itr1 == itr2 { + return itr1 + } + itr1, itr2 = itr1.Next, itr2.Next + } + + return nil +} + +func length(n *ListNode) int { + var l int + for n != nil { + l++ + n = n.Next + } + return l +} diff --git a/intersection_of_two_linked_lists_160/solution_test.go b/intersection_of_two_linked_lists_160/solution_test.go new file mode 100644 index 0000000..463f419 --- /dev/null +++ b/intersection_of_two_linked_lists_160/solution_test.go @@ -0,0 +1,15 @@ +package intersection_of_two_linked_lists_160 + +import ( + "testing" + + . "github.com/austingebauer/go-leetcode/structures" + "github.com/stretchr/testify/assert" +) + +func Test_getIntersectionNode(t *testing.T) { + intersectNode := &ListNode{Val: 8, Next: &ListNode{Val: 4, Next: &ListNode{Val: 5}}} + headA := &ListNode{Val: 4, Next: &ListNode{Val: 1, Next: intersectNode}} + headB := &ListNode{Val: 5, Next: &ListNode{Val: 6, Next: &ListNode{Val: 1, Next: intersectNode}}} + assert.Equal(t, intersectNode, getIntersectionNode(headA, headB)) +} 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_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) }) 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..8a53947 --- /dev/null +++ b/merge_strings_alternately_1768/solution.go @@ -0,0 +1,27 @@ +package merge_strings_alternately_1768 + +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..76688c3 --- /dev/null +++ b/merge_strings_alternately_1768/solution_test.go @@ -0,0 +1,49 @@ +package merge_strings_alternately_1768 + +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) + }) + } +} 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++ + } +} 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) { diff --git a/pascals_triangle_118/README.md b/pascals_triangle_118/README.md new file mode 100644 index 0000000..f334aef --- /dev/null +++ b/pascals_triangle_118/README.md @@ -0,0 +1,30 @@ +# 118. Pascal's Triangle + +https://leetcode.com/problems/pascals-triangle/ + +## Difficulty: + +Easy + +## Description + +Given an integer numRows, return the first numRows of Pascal's triangle. + +In Pascal's triangle, each number is the sum of the two numbers directly above it +as shown: + +![](https://upload.wikimedia.org/wikipedia/commons/0/0d/PascalTriangleAnimated2.gif) + +Example 1: +``` +Input: numRows = 5 +Output: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]] +``` +Example 2: +``` +Input: numRows = 1 +Output: [[1]] +``` + +Constraints: +- 1 <= numRows <= 30 diff --git a/pascals_triangle_118/solution.go b/pascals_triangle_118/solution.go new file mode 100644 index 0000000..f67a80f --- /dev/null +++ b/pascals_triangle_118/solution.go @@ -0,0 +1,18 @@ +package pascals_triangle_118 + +func generate(numRows int) [][]int { + res := make([][]int, 0, numRows) + for r := 0; r < numRows; r++ { + row := make([]int, r+1) + row[0], row[len(row)-1] = 1, 1 + + // Build the new row by using values from the previous row + for c := 1; c < len(row)-1; c++ { + row[c] = res[r-1][c-1] + res[r-1][c] + } + + res = append(res, row) + } + + return res +} diff --git a/pascals_triangle_118/solution_test.go b/pascals_triangle_118/solution_test.go new file mode 100644 index 0000000..5790da6 --- /dev/null +++ b/pascals_triangle_118/solution_test.go @@ -0,0 +1,46 @@ +package pascals_triangle_118 + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func Test_generate(t *testing.T) { + type args struct { + numRows int + } + tests := []struct { + name string + args args + want [][]int + }{ + { + name: "pascal's triangle", + args: args{ + numRows: 5, + }, + want: [][]int{ + {1}, + {1, 1}, + {1, 2, 1}, + {1, 3, 3, 1}, + {1, 4, 6, 4, 1}, + }, + }, + { + name: "pascal's triangle", + args: args{ + numRows: 1, + }, + want: [][]int{ + {1}, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equal(t, tt.want, generate(tt.args.numRows)) + }) + } +} diff --git a/plus_one_66/README.md b/plus_one_66/README.md new file mode 100644 index 0000000..9b067e4 --- /dev/null +++ b/plus_one_66/README.md @@ -0,0 +1,40 @@ +# 66. Plus One + +https://leetcode.com/problems/plus-one/ + +## Difficulty: + +Easy + +## Description + +Given a non-empty array of decimal digits representing a non-negative integer, increment one to the integer. + +The digits are stored such that the most significant digit is at the head of the list, and each +element in the array contains a single digit. + +You may assume the integer does not contain any leading zero, except the number 0 itself. + +Example 1: +``` +Input: digits = [1,2,3] +Output: [1,2,4] +Explanation: The array represents the integer 123. +``` + +Example 2: +``` +Input: digits = [4,3,2,1] +Output: [4,3,2,2] +Explanation: The array represents the integer 4321. +``` + +Example 3: +``` +Input: digits = [0] +Output: [1] +``` + +Constraints: +- 1 <= digits.length <= 100 +- 0 <= digits[i] <= 9 diff --git a/plus_one_66/solution.go b/plus_one_66/solution.go new file mode 100644 index 0000000..1be5bb8 --- /dev/null +++ b/plus_one_66/solution.go @@ -0,0 +1,22 @@ +package plus_one_66 + +func plusOne(digits []int) []int { + carry := 1 + for i := len(digits) - 1; i >= 0; i-- { + incr := digits[i] + carry + + if incr == 10 { + digits[i] = 0 + carry = 1 + } else { + digits[i] = incr + carry = 0 + } + } + + if carry == 1 { + return append([]int{1}, digits...) + } + + return digits +} diff --git a/plus_one_66/solution_test.go b/plus_one_66/solution_test.go new file mode 100644 index 0000000..3b70410 --- /dev/null +++ b/plus_one_66/solution_test.go @@ -0,0 +1,60 @@ +package plus_one_66 + +import ( + "reflect" + "testing" +) + +func Test_plusOne(t *testing.T) { + type args struct { + digits []int + } + tests := []struct { + name string + args args + want []int + }{ + { + name: "plus one", + args: args{ + digits: []int{1, 2, 3}, + }, + want: []int{1, 2, 4}, + }, + { + name: "plus one", + args: args{ + digits: []int{4, 3, 2, 1}, + }, + want: []int{4, 3, 2, 2}, + }, + { + name: "plus one", + args: args{ + digits: []int{0}, + }, + want: []int{1}, + }, + { + name: "plus one", + args: args{ + digits: []int{9, 9, 9}, + }, + want: []int{1, 0, 0, 0}, + }, + { + name: "plus one", + args: args{ + digits: []int{9}, + }, + want: []int{1, 0}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := plusOne(tt.args.digits); !reflect.DeepEqual(got, tt.want) { + t.Errorf("plusOne() = %v, want %v", got, tt.want) + } + }) + } +} 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) + } + }) + } +} 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 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)) +}