From be94a2753dfa948ae618ccf3bda7ef2adbea5663 Mon Sep 17 00:00:00 2001 From: Invidam Date: Wed, 24 Apr 2024 15:10:37 +0900 Subject: [PATCH 01/13] contains-duplicate: solve problem --- contains-duplicate/invidam.go | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 contains-duplicate/invidam.go diff --git a/contains-duplicate/invidam.go b/contains-duplicate/invidam.go new file mode 100644 index 000000000..9647fa5cf --- /dev/null +++ b/contains-duplicate/invidam.go @@ -0,0 +1,10 @@ +func containsDuplicate(nums []int) bool { + appeared := make(map[int]bool) + + for _, num := range nums { + if appeared[num] { + return true + } + appeared[num] = true + } +} From a8669dae31ce3d187738e9867e634d12f8614d43 Mon Sep 17 00:00:00 2001 From: Invidam Date: Wed, 24 Apr 2024 15:12:30 +0900 Subject: [PATCH 02/13] contains-duplicate: refactor - init map with size. - check exists only in if statement. --- contains-duplicate/invidam.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/contains-duplicate/invidam.go b/contains-duplicate/invidam.go index 9647fa5cf..092268745 100644 --- a/contains-duplicate/invidam.go +++ b/contains-duplicate/invidam.go @@ -1,10 +1,12 @@ func containsDuplicate(nums []int) bool { - appeared := make(map[int]bool) + appeared := make(map[int]bool, len(nums)) for _, num := range nums { - if appeared[num] { + if _, found := appeared[num]; found { return true } appeared[num] = true } -} + + return false +} \ No newline at end of file From 2b171cce6cedfc504e237e179425c7522268fb96 Mon Sep 17 00:00:00 2001 From: Invidam Date: Wed, 24 Apr 2024 15:13:16 +0900 Subject: [PATCH 03/13] contains-duplicate: adjust init size --- contains-duplicate/invidam.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contains-duplicate/invidam.go b/contains-duplicate/invidam.go index 092268745..7405cde5e 100644 --- a/contains-duplicate/invidam.go +++ b/contains-duplicate/invidam.go @@ -1,5 +1,5 @@ func containsDuplicate(nums []int) bool { - appeared := make(map[int]bool, len(nums)) + appeared := make(map[int]bool, len(nums)/4) for _, num := range nums { if _, found := appeared[num]; found { From 733fc966fbe05dec32b66cc8fb3cecc2508b846c Mon Sep 17 00:00:00 2001 From: Invidam Date: Wed, 24 Apr 2024 15:15:01 +0900 Subject: [PATCH 04/13] contains-duplicate: refactor function --- contains-duplicate/invidam.go | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/contains-duplicate/invidam.go b/contains-duplicate/invidam.go index 7405cde5e..9816d1f0c 100644 --- a/contains-duplicate/invidam.go +++ b/contains-duplicate/invidam.go @@ -1,12 +1,9 @@ func containsDuplicate(nums []int) bool { - appeared := make(map[int]bool, len(nums)/4) + appeared := make(map[int]bool) for _, num := range nums { - if _, found := appeared[num]; found { - return true - } appeared[num] = true } - return false -} \ No newline at end of file + return len(appeared) != len(nums) +} From 0280206a7ac001c033fd3aa90ab37c72ddd4d798 Mon Sep 17 00:00:00 2001 From: Invidam Date: Wed, 24 Apr 2024 16:35:24 +0900 Subject: [PATCH 05/13] valid-anagram: solve problem --- valid-anagram/invidam.go | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 valid-anagram/invidam.go diff --git a/valid-anagram/invidam.go b/valid-anagram/invidam.go new file mode 100644 index 000000000..5eb713bba --- /dev/null +++ b/valid-anagram/invidam.go @@ -0,0 +1,23 @@ +func isAnagram(s string, t string) bool { + freqS := make(map[rune]int, 26) + freqT := make(map[rune]int, 26) + + for _, ch := range s { + if _, ok := freqS[ch]; ok { + freqS[ch]++ + } else { + freqS[ch] = 1 + } + } + for _, ch := range t { + freqT[ch]++ + } + + for ch := 'a'; ch <= 'z'; ch++ { + if diff := freqS[ch] - freqT[ch]; diff != 0 { + return false + } + } + + return true +} From cf7e53eacef34b9b1ea2ed556501a9219edeb5e4 Mon Sep 17 00:00:00 2001 From: Invidam Date: Wed, 24 Apr 2024 16:57:26 +0900 Subject: [PATCH 06/13] two-sum: solve problem --- two-sum/invidam.go | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 two-sum/invidam.go diff --git a/two-sum/invidam.go b/two-sum/invidam.go new file mode 100644 index 000000000..654f001f4 --- /dev/null +++ b/two-sum/invidam.go @@ -0,0 +1,11 @@ +func twoSum(nums []int, target int) []int { + for i, ni := range nums { + for j, nj := range nums { + if i != j && ni+nj == target { + return []int{i, j} + } + } + } + + return nil +} From 58ad6dca75d5653af7a14c67f4c4d4c2ec96be03 Mon Sep 17 00:00:00 2001 From: Invidam Date: Wed, 24 Apr 2024 17:23:21 +0900 Subject: [PATCH 07/13] two-sum: sort version --- two-sum/invidam.go | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/two-sum/invidam.go b/two-sum/invidam.go index 654f001f4..c8ec3a2e9 100644 --- a/two-sum/invidam.go +++ b/two-sum/invidam.go @@ -1,9 +1,29 @@ +type NumAndIdx struct { + Num int + Idx int +} + func twoSum(nums []int, target int) []int { - for i, ni := range nums { - for j, nj := range nums { - if i != j && ni+nj == target { - return []int{i, j} - } + numAndIdxs := make([]NumAndIdx, 0, len(nums)) + for i, n := range nums { + numAndIdxs = append(numAndIdxs, NumAndIdx{Num: n, Idx: i}) + } + + sort.Slice(numAndIdxs, func(i, j int) bool { + return numAndIdxs[i].Num < numAndIdxs[j].Num + }) + + ldx, rdx := 0, len(numAndIdxs)-1 + + for ldx < rdx { + l := numAndIdxs[ldx] + r := numAndIdxs[rdx] + if sum := l.Num + r.Num; sum > target { + rdx-- + } else if sum < target { + ldx++ + } else { + return []int{l.Idx, r.Idx} } } From f3f5d84ad3d8e4cebfe9d4e18dc24f7071b047d0 Mon Sep 17 00:00:00 2001 From: Invidam Date: Wed, 24 Apr 2024 17:28:00 +0900 Subject: [PATCH 08/13] two-sum: map version --- two-sum/invidam.go | 29 ++++------------------------- 1 file changed, 4 insertions(+), 25 deletions(-) diff --git a/two-sum/invidam.go b/two-sum/invidam.go index c8ec3a2e9..b8956d26b 100644 --- a/two-sum/invidam.go +++ b/two-sum/invidam.go @@ -1,31 +1,10 @@ -type NumAndIdx struct { - Num int - Idx int -} - func twoSum(nums []int, target int) []int { - numAndIdxs := make([]NumAndIdx, 0, len(nums)) + need := make(map[int]int, len(nums)) for i, n := range nums { - numAndIdxs = append(numAndIdxs, NumAndIdx{Num: n, Idx: i}) - } - - sort.Slice(numAndIdxs, func(i, j int) bool { - return numAndIdxs[i].Num < numAndIdxs[j].Num - }) - - ldx, rdx := 0, len(numAndIdxs)-1 - - for ldx < rdx { - l := numAndIdxs[ldx] - r := numAndIdxs[rdx] - if sum := l.Num + r.Num; sum > target { - rdx-- - } else if sum < target { - ldx++ - } else { - return []int{l.Idx, r.Idx} + if j, ok := need[n]; ok { + return []int{i, j} } + need[target-n] = i } - return nil } From 921f9b9e267d8a5c4104aa846117e951473a8442 Mon Sep 17 00:00:00 2001 From: Invidam Date: Tue, 30 Apr 2024 18:01:17 +0900 Subject: [PATCH 09/13] valid-palindrome: string builder version --- valid-palindrome/invidam.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 valid-palindrome/invidam.go diff --git a/valid-palindrome/invidam.go b/valid-palindrome/invidam.go new file mode 100644 index 000000000..b110426fd --- /dev/null +++ b/valid-palindrome/invidam.go @@ -0,0 +1,16 @@ +func isPalindrome(s string) bool { + var sb strings.Builder + sb.Grow(len(s)) + for _, ch := range s { + if unicode.IsLetter(ch) || unicode.IsNumber(ch) { + sb.WriteRune(unicode.ToLower(ch)) + } + } + filtered := sb.String() + for ldx, rdx := 0, len(filtered)-1; ldx < rdx; ldx, rdx = ldx+1, rdx-1 { + if filtered[ldx] != filtered[rdx] { + return false + } + } + return true +} From a19cf61baa1ed5be1e1a99d9c5d43f9a3fbdf1d6 Mon Sep 17 00:00:00 2001 From: Invidam Date: Tue, 30 Apr 2024 18:02:18 +0900 Subject: [PATCH 10/13] valid-palindrome: string concat version --- valid-palindrome/invidam.go | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/valid-palindrome/invidam.go b/valid-palindrome/invidam.go index b110426fd..ec44ff741 100644 --- a/valid-palindrome/invidam.go +++ b/valid-palindrome/invidam.go @@ -1,13 +1,12 @@ func isPalindrome(s string) bool { - var sb strings.Builder - sb.Grow(len(s)) + filtered := "" for _, ch := range s { if unicode.IsLetter(ch) || unicode.IsNumber(ch) { - sb.WriteRune(unicode.ToLower(ch)) + filtered += string(unicode.ToLower(ch)) } } - filtered := sb.String() - for ldx, rdx := 0, len(filtered)-1; ldx < rdx; ldx, rdx = ldx+1, rdx-1 { + + for ldx, rdx := 0, len(filtered) - 1; ldx < rdx; ldx, rdx = ldx + 1, rdx - 1 { if filtered[ldx] != filtered[rdx] { return false } From 555ea0581d3a3934e6283df64215be6460ec5059 Mon Sep 17 00:00:00 2001 From: Invidam Date: Tue, 30 Apr 2024 18:22:48 +0900 Subject: [PATCH 11/13] valid-palindrome: map function version --- valid-palindrome/invidam.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/valid-palindrome/invidam.go b/valid-palindrome/invidam.go index ec44ff741..ad1acb0eb 100644 --- a/valid-palindrome/invidam.go +++ b/valid-palindrome/invidam.go @@ -1,10 +1,10 @@ func isPalindrome(s string) bool { - filtered := "" - for _, ch := range s { - if unicode.IsLetter(ch) || unicode.IsNumber(ch) { - filtered += string(unicode.ToLower(ch)) + filtered := strings.Map(func(r rune) rune { + if !unicode.IsLetter(r) && !unicode.IsNumber(r) { + return -1 } - } + return unicode.ToLower(r) + }, s) for ldx, rdx := 0, len(filtered) - 1; ldx < rdx; ldx, rdx = ldx + 1, rdx - 1 { if filtered[ldx] != filtered[rdx] { From 8678b9ac3dacd5f004177fab026f5a0a483b1129 Mon Sep 17 00:00:00 2001 From: Invidam Date: Tue, 30 Apr 2024 18:28:00 +0900 Subject: [PATCH 12/13] best-time-to-buy-and-sell-stock: solve problem --- best-time-to-buy-and-sell-stock/invidam.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 best-time-to-buy-and-sell-stock/invidam.go diff --git a/best-time-to-buy-and-sell-stock/invidam.go b/best-time-to-buy-and-sell-stock/invidam.go new file mode 100644 index 000000000..35185a3a3 --- /dev/null +++ b/best-time-to-buy-and-sell-stock/invidam.go @@ -0,0 +1,12 @@ +func maxProfit(prices []int) int { + maxPriceFrom := make([]int, len(prices)+1) + for i := len(prices) - 1; i >= 0; i-- { + maxPriceFrom[i] = max(maxPriceFrom[i+1], prices[i]) + } + + maxPriceDiff := 0 + for i, price := range prices { + maxPriceDiff = max(maxPriceDiff, maxPriceFrom[i+1]-price) + } + return maxPriceDiff +} From 59f2aedce547f5acd57808a8d304e4f9f3f58ffc Mon Sep 17 00:00:00 2001 From: Invidam Date: Tue, 30 Apr 2024 19:21:35 +0900 Subject: [PATCH 13/13] best-time-to-buy-and-sell-stock: use greedy algorithm --- best-time-to-buy-and-sell-stock/invidam.go | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/best-time-to-buy-and-sell-stock/invidam.go b/best-time-to-buy-and-sell-stock/invidam.go index 35185a3a3..55671947e 100644 --- a/best-time-to-buy-and-sell-stock/invidam.go +++ b/best-time-to-buy-and-sell-stock/invidam.go @@ -1,12 +1,10 @@ func maxProfit(prices []int) int { - maxPriceFrom := make([]int, len(prices)+1) - for i := len(prices) - 1; i >= 0; i-- { - maxPriceFrom[i] = max(maxPriceFrom[i+1], prices[i]) - } + purchasePrice := prices[0] + maxBenefit := 0 - maxPriceDiff := 0 - for i, price := range prices { - maxPriceDiff = max(maxPriceDiff, maxPriceFrom[i+1]-price) + for _, price := range prices { + purchasePrice = min(purchasePrice, price) + maxBenefit = max(maxBenefit, price-purchasePrice) } - return maxPriceDiff + return maxBenefit }