From 1c1328ff20a4810529edfabbf2a5567300ec9bd0 Mon Sep 17 00:00:00 2001 From: Austin Gebauer Date: Tue, 7 Jan 2025 20:59:10 -0800 Subject: [PATCH 1/3] 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 2/3] 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 3/3] 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)) +}