From b8168edb3ce0d1d5bbaa4ebc88530245d542a510 Mon Sep 17 00:00:00 2001 From: Ted Date: Wed, 1 Apr 2026 01:58:49 -0400 Subject: [PATCH] add week 5 solutions --- best-time-to-buy-and-sell-stock/tedkimdev.go | 20 ++++++ encode-and-decode-strings/tedkimdev.go | 32 ++++++++++ group-anagrams/tedkimdev.go | 19 ++++++ implement-trie-prefix-tree/tedkimdev.go | 52 +++++++++++++++ word-break/tedkimdev.go | 67 ++++++++++++++++++++ 5 files changed, 190 insertions(+) create mode 100644 best-time-to-buy-and-sell-stock/tedkimdev.go create mode 100644 encode-and-decode-strings/tedkimdev.go create mode 100644 group-anagrams/tedkimdev.go create mode 100644 implement-trie-prefix-tree/tedkimdev.go create mode 100644 word-break/tedkimdev.go diff --git a/best-time-to-buy-and-sell-stock/tedkimdev.go b/best-time-to-buy-and-sell-stock/tedkimdev.go new file mode 100644 index 0000000000..bc7f9a3d3d --- /dev/null +++ b/best-time-to-buy-and-sell-stock/tedkimdev.go @@ -0,0 +1,20 @@ +// TC: O(n) +// SC: O(1) +func maxProfit(prices []int) int { + l, r := 0, 1 + max := 0 + + for r < len(prices) { + if prices[l] < prices[r] { + profit := prices[r] - prices[l] + if profit > max { + max = profit + } + } else { + l = r + } + r++ + } + + return max +} diff --git a/encode-and-decode-strings/tedkimdev.go b/encode-and-decode-strings/tedkimdev.go new file mode 100644 index 0000000000..1183a7b7d0 --- /dev/null +++ b/encode-and-decode-strings/tedkimdev.go @@ -0,0 +1,32 @@ +type Solution struct{} + +// TC: O(m) +// SC: O(m + n) +func (s *Solution) Encode(strs []string) string { + encoded := "" + for _, str := range strs { + encoded += fmt.Sprintf("%d|%s", len(str), str) + } + + return encoded +} + +// TC: O(m) +// SC: O(m + n) +func (s *Solution) Decode(encoded string) []string { + decoded := make([]string, 0) + + i := 0 + for i < len(encoded) { + j := i + for encoded[j] != '|' { + j++ + } + length, _ := strconv.Atoi(encoded[i:j]) + i = j + 1 + decoded = append(decoded, encoded[i:i+length]) + i += length + } + + return decoded +} diff --git a/group-anagrams/tedkimdev.go b/group-anagrams/tedkimdev.go new file mode 100644 index 0000000000..7315d5189b --- /dev/null +++ b/group-anagrams/tedkimdev.go @@ -0,0 +1,19 @@ +// TC: O(m * n) +// SC: O(m * n) +func groupAnagrams(strs []string) [][]string { + groups := map[[26]int][]string{} + + for _, s := range strs { + var count [26]int + for _, c := range s { + count[c-'a']++ + } + groups[count] = append(groups[count], s) + } + + result := [][]string{} + for _, group := range groups { + result = append(result, group) + } + return result +} diff --git a/implement-trie-prefix-tree/tedkimdev.go b/implement-trie-prefix-tree/tedkimdev.go new file mode 100644 index 0000000000..fb8e5757e9 --- /dev/null +++ b/implement-trie-prefix-tree/tedkimdev.go @@ -0,0 +1,52 @@ +// TC: O(n) +// SC: O(t) - Where n is the length of the string and t is the total number of TrieNodes created in the Trie. +type PrefixTree struct { + children map[rune]*PrefixTree + isWord bool +} + +func Constructor() PrefixTree { + return PrefixTree{ + children: map[rune]*PrefixTree{}, + isWord: false, + } +} + +func (this *PrefixTree) Insert(word string) { + cur := this + for _, c := range word { + if _, ok := cur.children[c]; !ok { + child := Constructor() + cur.children[c] = &child + cur = cur.children[c] + } else { + cur = cur.children[c] + } + } + cur.isWord = true +} + +func (this *PrefixTree) Search(word string) bool { + cur := this + for _, c := range word { + if _, ok := cur.children[c]; ok { + cur = cur.children[c] + } else { + return false + } + } + return cur.isWord +} + +func (this *PrefixTree) StartsWith(prefix string) bool { + cur := this + for _, c := range prefix { + if _, ok := cur.children[c]; ok { + cur = cur.children[c] + } else { + return false + } + } + + return cur != nil +} diff --git a/word-break/tedkimdev.go b/word-break/tedkimdev.go new file mode 100644 index 0000000000..e382241abb --- /dev/null +++ b/word-break/tedkimdev.go @@ -0,0 +1,67 @@ +// TC: O((n * t) + (m * t)) +// SC: O(n + (m * t)) +func wordBreak(s string, wordDict []string) bool { + trie := NewTrieNode() + maxLength := 0 + for _, word := range wordDict { + trie.Insert(word) + if len(word) > maxLength { + maxLength = len(word) + } + } + + dp := make([]bool, len(s)+1) + dp[len(s)] = true + + for i := len(s) - 1; i >= 0; i-- { + node := trie + for j := i; j < len(s) && j < i+maxLength; j++ { + c := s[j] + if _, ok := node.children[rune(c)]; !ok { + break + } + node = node.children[rune(c)] + + if node.isWord && dp[j+1] { + dp[i] = true + break + } + } + } + + return dp[0] +} + +type TrieNode struct { + children map[rune]*TrieNode + isWord bool +} + +func NewTrieNode() *TrieNode { + return &TrieNode{children: make(map[rune]*TrieNode)} +} + +func (t *TrieNode) Insert(word string) { + node := t + for _, char := range word { + if _, ok := node.children[char]; !ok { + node.children[char] = NewTrieNode() + } + node = node.children[char] + } + node.isWord = true +} + +// func (t *TrieNode) Search(s string, i, j int) bool { +// node := t +// for idx := i; idx <= j; idx++ { +// char := rune(s[idx]) +// if _, ok := node.children[char]; !ok { +// return false +// } +// node = node.children[char] +// } +// return node.isWord +// } + +