diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..efb9808 --- /dev/null +++ b/LICENSE @@ -0,0 +1,24 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..ecbfafa --- /dev/null +++ b/Makefile @@ -0,0 +1,4 @@ +lint: + golangci-lint run ./... + +.PHONY: lint diff --git a/create.sh b/create.sh new file mode 100755 index 0000000..cd8458f --- /dev/null +++ b/create.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +num=$1 + +echo "$num" | grep -q "^[1-9][0-9]\{,4\}$" || { + echo "Err: no valid number given" >&2 + exit 1 +} + +parent=$((num / 100)) +pdir="solutions/${parent}/q${num}" +sol_file="${pdir}/solution.go" + +if [ -f "$sol_file" ]; then + exit 0 +fi + +echo "Creating template for question No. $num" >&2 +mkdir -pv "$pdir" +echo "package q$num" > "$sol_file" +echo "Created $sol_file" diff --git a/go.mod b/go.mod index e062fa1..9e38376 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,15 @@ module leetcode-go go 1.25.5 + +require ( + github.com/emirpasic/gods/v2 v2.0.0-alpha + github.com/k0kubun/pp/v3 v3.5.0 +) + +require ( + github.com/mattn/go-colorable v0.1.14 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + golang.org/x/sys v0.29.0 // indirect + golang.org/x/text v0.26.0 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..0aa4e6a --- /dev/null +++ b/go.sum @@ -0,0 +1,13 @@ +github.com/emirpasic/gods/v2 v2.0.0-alpha h1:dwFlh8pBg1VMOXWGipNMRt8v96dKAIvBehtCt6OtunU= +github.com/emirpasic/gods/v2 v2.0.0-alpha/go.mod h1:W0y4M2dtBB9U5z3YlghmpuUhiaZT2h6yoeE+C1sCp6A= +github.com/k0kubun/pp/v3 v3.5.0 h1:iYNlYA5HJAJvkD4ibuf9c8y6SHM0QFhaBuCqm1zHp0w= +github.com/k0kubun/pp/v3 v3.5.0/go.mod h1:5lzno5ZZeEeTV/Ky6vs3g6d1U3WarDrH8k240vMtGro= +github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= +github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= +golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M= +golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA= diff --git a/solutions/0/q15/solution.go b/solutions/0/q15/solution.go new file mode 100644 index 0000000..69d9fcd --- /dev/null +++ b/solutions/0/q15/solution.go @@ -0,0 +1,65 @@ +package q15 + +import "slices" + +func sortAndDedup3(nums []int) []int { + slices.Sort(nums) + head, dup := 0, 0 + for i := 1; i < len(nums); i++ { + if nums[i] == nums[head] { + dup++ + } else { + dup = 0 + } + if dup < 3 { + head++ + nums[head] = nums[i] + } + } + return nums[:head+1] +} + +func threeSum(nums []int) [][]int { + nums = sortAndDedup3(nums) + ret := [][]int{} + + appendResult := func(a, b, c int) { + triplet := []int{a, b, c} + if len(ret) > 0 && slices.Equal(triplet, ret[len(ret)-1]) { + return + } + ret = append(ret, triplet) + } + + for i := 0; i < len(nums)-2; i++ { + if nums[i] > 0 { + break + } + wants := -nums[i] + l, r := i+1, len(nums)-1 + for l < r { + for l < r && nums[l]+nums[r] > wants { + r-- + } + if l < r && nums[l]+nums[r] == wants { + appendResult(nums[i], nums[l], nums[r]) + r-- + } + for l < r && nums[l]+nums[r] < wants { + l++ + } + if l < r && nums[l]+nums[r] == wants { + appendResult(nums[i], nums[l], nums[r]) + l++ + } + } + + // skip same numbers + for ; i < len(nums)-2 && nums[i] == nums[i+1]; i++ { + } + } + + return ret +} + +var _ = threeSum diff --git a/solutions/0/q17/solution.go b/solutions/0/q17/solution.go new file mode 100644 index 0000000..632e70d --- /dev/null +++ b/solutions/0/q17/solution.go @@ -0,0 +1,39 @@ +package q17 + +var alphabets = [][]byte{ + []byte("abc"), + []byte("def"), + []byte("ghi"), + []byte("jkl"), + []byte("mno"), + []byte("pqrs"), + []byte("tuv"), + []byte("wxyz"), +} + +func combinations(offsets []int, i int, buffer []byte, strings []string) []string { + if buffer == nil { + buffer = make([]byte, len(offsets)) + } + + if i == len(offsets) { + return append(strings, string(buffer)) + } + + for _, c := range alphabets[offsets[i]] { + buffer[i] = c + strings = combinations(offsets, i+1, buffer, strings) + } + return strings +} + +func letterCombinations(digits string) []string { + offsets := make([]int, len(digits)) + for i := range len(digits) { + offsets[i] = int(digits[i] - '2') + } + + return combinations(offsets, 0, nil, []string{}) +} + +var _ = letterCombinations diff --git a/solutions/0/q20/solution.go b/solutions/0/q20/solution.go new file mode 100644 index 0000000..254d63b --- /dev/null +++ b/solutions/0/q20/solution.go @@ -0,0 +1,32 @@ +package q20 + +func isValid(s string) bool { + stack := make([]byte, 0, len(s)/2) + + for i := range len(s) { + switch s[i] { + case '(', '[', '{': + stack = append(stack, s[i]) + case ')': + if len(stack) == 0 || stack[len(stack)-1] != '(' { + return false + } + stack = stack[:len(stack)-1] + + case ']': + if len(stack) == 0 || stack[len(stack)-1] != '[' { + return false + } + stack = stack[:len(stack)-1] + + case '}': + if len(stack) == 0 || stack[len(stack)-1] != '{' { + return false + } + stack = stack[:len(stack)-1] + } + } + return len(stack) == 0 +} + +var _ = isValid diff --git a/solutions/0/q35/solution.go b/solutions/0/q35/solution.go new file mode 100644 index 0000000..15f6011 --- /dev/null +++ b/solutions/0/q35/solution.go @@ -0,0 +1,19 @@ +package q35 + +func searchInsert(nums []int, target int) int { + l, r := 0, len(nums) + for l < r { + mid := (l + r) / 2 + switch { + case nums[mid] == target: + return mid + case nums[mid] > target: + r = mid + default: + l = mid + 1 + } + } + return l +} + +var _ = searchInsert diff --git a/solutions/q36/solution.go b/solutions/0/q36/solution.go similarity index 100% rename from solutions/q36/solution.go rename to solutions/0/q36/solution.go diff --git a/solutions/0/q53/solution.go b/solutions/0/q53/solution.go new file mode 100644 index 0000000..af32086 --- /dev/null +++ b/solutions/0/q53/solution.go @@ -0,0 +1,18 @@ +package q53 + +import "math" + +func maxSubArray(nums []int) int { + sum := 0 + minSubstract := 0 + maxSubArr := math.MinInt + for i := range nums { + sum += nums[i] + nums[i] = sum + maxSubArr = max(maxSubArr, nums[i]-minSubstract) + minSubstract = min(minSubstract, nums[i]) + } + return maxSubArr +} + +var _ = maxSubArray diff --git a/solutions/0/q66/solution.go b/solutions/0/q66/solution.go new file mode 100644 index 0000000..fdcfb96 --- /dev/null +++ b/solutions/0/q66/solution.go @@ -0,0 +1,22 @@ +package q66 + +func plusOne(digits []int) []int { + digits[len(digits)-1]++ + for i := len(digits) - 1; i > 0; i-- { + if digits[i] > 9 { + digits[i] -= 10 + digits[i-1]++ + } else { + break + } + } + if digits[0] > 9 { + digits[0] -= 10 + ret := make([]int, 0, len(digits)+1) + ret = append(ret, 1) + return append(ret, digits...) + } + return digits +} + +var _ = plusOne diff --git a/solutions/0/q67/solution.go b/solutions/0/q67/solution.go new file mode 100644 index 0000000..b1618ef --- /dev/null +++ b/solutions/0/q67/solution.go @@ -0,0 +1,28 @@ +package q67 + +func toDigit(byt byte) uint8 { return byt - '0' } +func toByte(digit uint8) byte { return '0' + digit } + +func addBinary(a string, b string) string { + lenA, lenB := len(a), len(b) + ret := make([]byte, max(lenA, lenB)+1) + var carry uint8 + for i := range ret { + d := carry + if i < lenA { + d += toDigit(a[lenA-i-1]) + } + if i < lenB { + d += toDigit(b[lenB-i-1]) + } + carry = d / 2 + ret[len(ret)-i-1] = toByte(d % 2) + } + + if ret[0] != '1' { + return string(ret[1:]) + } + return string(ret) +} + +var _ = addBinary diff --git a/solutions/0/q69/solution.go b/solutions/0/q69/solution.go new file mode 100644 index 0000000..f02eb65 --- /dev/null +++ b/solutions/0/q69/solution.go @@ -0,0 +1,26 @@ +package q69 + +func mySqrt(x int) int { + if x < 2 { + return x + } + l, r := 0, x/2+1 + for l < r { + m := (l + r) / 2 + sq := m * m + switch { + case sq == x: + return m + case sq < x: + if (m+1)*(m+1) > x { + return m + } + l = m + 1 + case sq > x: + r = m + } + } + return -1 +} + +var _ = mySqrt diff --git a/solutions/0/q70/solution.go b/solutions/0/q70/solution.go new file mode 100644 index 0000000..540545d --- /dev/null +++ b/solutions/0/q70/solution.go @@ -0,0 +1,24 @@ +package q70 + +func nWays(n, i int, cache []int) int { + if i == n { + return 1 + } + if i > n { + return 0 + } + if cache == nil { + cache = make([]int, n) + } else if cache[i] != 0 { + return cache[i] + } + ret := nWays(n, i+1, cache) + nWays(n, i+2, cache) + cache[i] = ret + return ret +} + +func climbStairs(n int) int { + return nWays(n, 0, nil) +} + +var _ = climbStairs diff --git a/solutions/0/q9/solution.go b/solutions/0/q9/solution.go new file mode 100644 index 0000000..faf307a --- /dev/null +++ b/solutions/0/q9/solution.go @@ -0,0 +1,18 @@ +package q9 + +import "strconv" + +func isPalindrome(x int) bool { + if x < 0 { + return false + } + str := strconv.FormatInt(int64(x), 10) + for i := range len(str) / 2 { + if str[i] != str[len(str)-1-i] { + return false + } + } + return true +} + +var _ = isPalindrome diff --git a/solutions/1/q104/solution.go b/solutions/1/q104/solution.go new file mode 100644 index 0000000..78fa9ca --- /dev/null +++ b/solutions/1/q104/solution.go @@ -0,0 +1,20 @@ +package q104 + +type TreeNode struct { + Val int + Left *TreeNode + Right *TreeNode +} + +func md(d int, node *TreeNode) int { + if node == nil { + return d - 1 + } + return max(md(d+1, node.Left), md(d+1, node.Right)) +} + +func maxDepth(root *TreeNode) int { + return md(1, root) +} + +var _ = maxDepth diff --git a/solutions/1/q108/solution.go b/solutions/1/q108/solution.go new file mode 100644 index 0000000..2de7147 --- /dev/null +++ b/solutions/1/q108/solution.go @@ -0,0 +1,26 @@ +package q108 + +type TreeNode struct { + Val int + Left *TreeNode + Right *TreeNode +} + +func sortedArrayToBST(nums []int) *TreeNode { + if len(nums) == 0 { + return nil + } + if len(nums) == 1 { + return &TreeNode{Val: nums[0]} + } + + l, r := nums[:len(nums)/2], nums[len(nums)/2+1:] + m := nums[len(nums)/2] + return &TreeNode{ + Val: m, + Left: sortedArrayToBST(l), + Right: sortedArrayToBST(r), + } +} + +var _ = sortedArrayToBST diff --git a/solutions/1/q120/solution.go b/solutions/1/q120/solution.go new file mode 100644 index 0000000..5978b01 --- /dev/null +++ b/solutions/1/q120/solution.go @@ -0,0 +1,14 @@ +package q120 + +func minimumTotal(triangle [][]int) int { + size := len(triangle) + + for row := size - 2; row >= 0; row-- { + for i := range triangle[row] { + triangle[row][i] += min(triangle[row+1][i], triangle[row+1][i+1]) + } + } + return triangle[0][0] +} + +var _ = minimumTotal diff --git a/solutions/q125/solution.go b/solutions/1/q125/solution.go similarity index 100% rename from solutions/q125/solution.go rename to solutions/1/q125/solution.go diff --git a/solutions/q134/solution.go b/solutions/1/q134/solution.go similarity index 100% rename from solutions/q134/solution.go rename to solutions/1/q134/solution.go diff --git a/solutions/q134/solution_test.go b/solutions/1/q134/solution_test.go similarity index 100% rename from solutions/q134/solution_test.go rename to solutions/1/q134/solution_test.go diff --git a/solutions/q135/solution.go b/solutions/1/q135/solution.go similarity index 100% rename from solutions/q135/solution.go rename to solutions/1/q135/solution.go diff --git a/solutions/1/q136/solution.go b/solutions/1/q136/solution.go new file mode 100644 index 0000000..f1a8404 --- /dev/null +++ b/solutions/1/q136/solution.go @@ -0,0 +1,11 @@ +package q136 + +func singleNumber(nums []int) int { + x := 0 + for _, num := range nums { + x ^= num + } + return x +} + +var _ = singleNumber diff --git a/solutions/1/q141/solution.go b/solutions/1/q141/solution.go new file mode 100644 index 0000000..e927c9f --- /dev/null +++ b/solutions/1/q141/solution.go @@ -0,0 +1,28 @@ +package q141 + +type ListNode struct { + Val int + Next *ListNode +} + +func hasCycle(head *ListNode) bool { + if head == nil { + return false + } + + p1, p2 := head, head + for { + for range 2 { + p2 = p2.Next + switch p2 { + case nil: + return false + case p1: + return true + } + } + p1 = p1.Next + } +} + +var _ = hasCycle diff --git a/solutions/q150/solution.go b/solutions/1/q150/solution.go similarity index 100% rename from solutions/q150/solution.go rename to solutions/1/q150/solution.go diff --git a/solutions/1/q190/solution.go b/solutions/1/q190/solution.go new file mode 100644 index 0000000..31c77df --- /dev/null +++ b/solutions/1/q190/solution.go @@ -0,0 +1,13 @@ +package q190 + +func reverseBits(n int) int { + ret := 0 + for i := range 32 { + if n|(1< 0; n >>= 1 { + if n|1 == n { + num++ + } + } + return num +} + +var _ = hammingWeight diff --git a/solutions/1/q199/solution.go b/solutions/1/q199/solution.go new file mode 100644 index 0000000..3ee35a9 --- /dev/null +++ b/solutions/1/q199/solution.go @@ -0,0 +1,37 @@ +package q199 + +type TreeNode struct { + Val int + Left *TreeNode + Right *TreeNode +} + +func rightSideView(root *TreeNode) []int { + ret := []int{} + + type qElem struct { + height int + node *TreeNode + } + + queue := []qElem{{0, root}} + var last *qElem + for ; len(queue) > 0; queue = queue[1:] { + cur := &queue[0] + if cur.node == nil { + continue + } + if last != nil && last.height < cur.height { + ret = append(ret, last.node.Val) + } + last = cur + queue = append(queue, qElem{cur.height + 1, cur.node.Left}, qElem{cur.height + 1, cur.node.Right}) + } + if last != nil { + ret = append(ret, last.node.Val) + } + + return ret +} + +var _ = rightSideView diff --git a/solutions/2/q200/solution.go b/solutions/2/q200/solution.go new file mode 100644 index 0000000..9564d9a --- /dev/null +++ b/solutions/2/q200/solution.go @@ -0,0 +1,31 @@ +package q200 + +const ( + VISITED byte = '.' + LAND byte = '1' +) + +func traverse(grid [][]byte, x, y int) int { + if x < 0 || y < 0 || x >= len(grid[0]) || y >= len(grid) || grid[y][x] != LAND { + return 0 + } + + grid[y][x] = VISITED + traverse(grid, x+1, y) + traverse(grid, x-1, y) + traverse(grid, x, y+1) + traverse(grid, x, y-1) + return 1 +} + +func numIslands(grid [][]byte) int { + count := 0 + for y := range grid { + for x := range grid[y] { + count += traverse(grid, x, y) + } + } + return count +} + +var _ = numIslands diff --git a/solutions/2/q208/solution.go b/solutions/2/q208/solution.go new file mode 100644 index 0000000..87c3ca2 --- /dev/null +++ b/solutions/2/q208/solution.go @@ -0,0 +1,105 @@ +package q208 + +type tNode struct { + str string + childs [26]*tNode + hasWord bool +} + +func (n *tNode) index() int { return index(n.str) } + +func (n *tNode) split(prefixLen int) (*tNode, *tNode) { + if len(n.str) < prefixLen { + panic("cannot split node") + } + if len(n.str) == prefixLen { + return n, nil + } + + prefix := n.str[:prefixLen] + n.str = n.str[prefixLen:] + p := &tNode{str: prefix} + p.childs[n.index()] = n + return p, n +} + +func commonPrefix(a, b string) int { + minLen := min(len(a), len(b)) + for i := range minLen { + if a[i] != b[i] { + return i + } + } + return minLen +} + +func index(str string) int { + if len(str) > 0 { + return int(str[0] - 'a') + } + return -1 // root +} + +type Trie struct { + root *tNode +} + +func Constructor() Trie { + return Trie{ + root: &tNode{}, + } +} + +func (t *Trie) Insert(word string) { + node := t.root + for len(word) > 0 { + idx := index(word) + next := node.childs[idx] + if next != nil { + pflen := commonPrefix(word, next.str) + next, _ = next.split(pflen) + node.childs[next.index()] = next + word = word[pflen:] + } else { + next = &tNode{str: word} + word = "" + node.childs[idx] = next + } + node = next + } + node.hasWord = true +} + +func (t *Trie) Search(word string) bool { + node := t.root + for len(word) > 0 { + next := node.childs[index(word)] + if next == nil { + return false + } + pflen := commonPrefix(word, next.str) + if pflen != len(next.str) { + return false + } + word = word[pflen:] + node = next + } + return node.hasWord +} + +func (t *Trie) StartsWith(prefix string) bool { + node := t.root + for len(prefix) > 0 { + next := node.childs[index(prefix)] + if next == nil { + return false + } + pflen := commonPrefix(prefix, next.str) + if pflen != len(next.str) && pflen != len(prefix) { + return false + } + prefix = prefix[pflen:] + node = next + } + return true +} diff --git a/solutions/q209/solution.go b/solutions/2/q209/solution.go similarity index 100% rename from solutions/q209/solution.go rename to solutions/2/q209/solution.go diff --git a/solutions/2/q215/solution.go b/solutions/2/q215/solution.go new file mode 100644 index 0000000..41c54d3 --- /dev/null +++ b/solutions/2/q215/solution.go @@ -0,0 +1,37 @@ +package q215 + +func findKthLargest(nums []int, k int) int { + // build max-heap + for i := 1; i < len(nums); i++ { + for j := i; j > 0; j = (j - 1) / 2 { + parent := (j - 1) / 2 + if nums[j] > nums[parent] { + nums[j], nums[parent] = nums[parent], nums[j] + } + } + } + + for range k - 1 { + // pop the heap + nums[0] = nums[len(nums)-1] + nums = nums[:len(nums)-1] + + i := 0 + for i*2+1 < len(nums) { + l, r := i*2+1, i*2+2 + next := l + if r < len(nums) && nums[r] > nums[l] { + next = r + } + if nums[i] >= nums[next] { + break + } + nums[i], nums[next] = nums[next], nums[i] + i = next + } + } + + return nums[0] +} + +var _ = findKthLargest diff --git a/solutions/2/q228/solution.go b/solutions/2/q228/solution.go new file mode 100644 index 0000000..15e303f --- /dev/null +++ b/solutions/2/q228/solution.go @@ -0,0 +1,32 @@ +package q228 + +import ( + "fmt" + "strconv" +) + +func addToRanges(output []string, a, b int) []string { + if a == b { + return append(output, strconv.FormatInt(int64(a), 10)) + } + return append(output, fmt.Sprintf("%d->%d", a, b)) +} + +func summaryRanges(nums []int) []string { + if len(nums) == 0 { + return nil + } + + output := []string{} + l := 0 + for r := 1; r < len(nums); r++ { + if nums[r]-nums[r-1] != 1 { + output = addToRanges(output, nums[l], nums[r-1]) + l = r + } + } + output = addToRanges(output, nums[l], nums[len(nums)-1]) + return output +} + +var _ = summaryRanges diff --git a/solutions/q238/solution.go b/solutions/2/q238/solution.go similarity index 100% rename from solutions/q238/solution.go rename to solutions/2/q238/solution.go diff --git a/solutions/q238/solution_test.go b/solutions/2/q238/solution_test.go similarity index 100% rename from solutions/q238/solution_test.go rename to solutions/2/q238/solution_test.go diff --git a/solutions/24/q2483/solution.go b/solutions/24/q2483/solution.go new file mode 100644 index 0000000..2e6b54e --- /dev/null +++ b/solutions/24/q2483/solution.go @@ -0,0 +1,29 @@ +package q2483 + +func bestClosingTime(customers string) int { + numY := 0 + for i := range len(customers) { + if customers[i] == 'Y' { + numY++ + } + } + minCloseHour := 0 + minPenalty := numY + penalty := numY + for i := range len(customers) { + // close at (i + 1)th hour + switch customers[i] { + case 'N': + penalty++ + case 'Y': + penalty-- + } + if penalty < minPenalty { + minPenalty = penalty + minCloseHour = i + 1 + } + } + return minCloseHour +} + +var _ = bestClosingTime diff --git a/solutions/q380/solution.go b/solutions/3/q380/solution.go similarity index 100% rename from solutions/q380/solution.go rename to solutions/3/q380/solution.go diff --git a/solutions/3/q383/solution.go b/solutions/3/q383/solution.go new file mode 100644 index 0000000..8e6f390 --- /dev/null +++ b/solutions/3/q383/solution.go @@ -0,0 +1,25 @@ +package q383 + +func canConstruct(ransomNote string, magazine string) bool { + counts := make([]int, 'z'-'a'+1) + + for _, c := range magazine { + if c < 'a' || c > 'z' { + continue + } + counts[int(c)-int('a')]++ + } + for _, c := range ransomNote { + if c < 'a' || c > 'z' { + continue + } + offset := int(c) - int('a') + counts[offset]-- + if counts[offset] < 0 { + return false + } + } + return true +} + +var _ = canConstruct diff --git a/solutions/30/q3075/solution.go b/solutions/30/q3075/solution.go new file mode 100644 index 0000000..e319b8d --- /dev/null +++ b/solutions/30/q3075/solution.go @@ -0,0 +1,14 @@ +package q3075 + +import "slices" + +func maximumHappinessSum(happiness []int, k int) int64 { + slices.Sort(happiness) + var sum int64 + for i := range k { + sum += max(0, int64(happiness[len(happiness)-1-i]-i)) + } + return sum +} + +var _ = maximumHappinessSum diff --git a/solutions/5/q530/solution.go b/solutions/5/q530/solution.go new file mode 100644 index 0000000..673014c --- /dev/null +++ b/solutions/5/q530/solution.go @@ -0,0 +1,37 @@ +package q530 + +import "math" + +type TreeNode struct { + Val int + Left *TreeNode + Right *TreeNode +} + +func getMinimumDifference(root *TreeNode) int { + minDiff := math.MaxInt + var last *int + + var check = func(num int) { + if last == nil { + last = &num + return + } + minDiff = min(minDiff, num-*last) + *last = num + } + var traverse func(node *TreeNode) + traverse = func(node *TreeNode) { + if node == nil { + return + } + traverse(node.Left) + check(node.Val) + traverse(node.Right) + } + traverse(root) + + return minDiff +} + +var _ = getMinimumDifference diff --git a/solutions/6/q637/solution.go b/solutions/6/q637/solution.go new file mode 100644 index 0000000..a6822d5 --- /dev/null +++ b/solutions/6/q637/solution.go @@ -0,0 +1,43 @@ +package q637 + +type TreeNode struct { + Val int + Left *TreeNode + Right *TreeNode +} + +func averageOfLevels(root *TreeNode) []float64 { + type qElem struct { + level int + node *TreeNode + } + + ret := []float64{} + level := 0 + n := 0 // number of nodes + var sum float64 + + queue := []qElem{{level: 0, node: root}} + for ; len(queue) > 0; queue = queue[1:] { + curr := &queue[0] + if curr.level == level { + sum += float64(curr.node.Val) + n++ + } else { + ret = append(ret, sum/float64(n)) + sum = float64(curr.node.Val) + n = 1 + level = curr.level + } + if curr.node.Left != nil { + queue = append(queue, qElem{curr.level + 1, curr.node.Left}) + } + if curr.node.Right != nil { + queue = append(queue, qElem{curr.level + 1, curr.node.Right}) + } + } + ret = append(ret, sum/float64(n)) + return ret +} + +var _ = averageOfLevels diff --git a/solutions/9/q909/solution.go b/solutions/9/q909/solution.go new file mode 100644 index 0000000..bd1e397 --- /dev/null +++ b/solutions/9/q909/solution.go @@ -0,0 +1,50 @@ +package q909 + +func coord(n, num int) (x, y int) { + num -= 1 + row := num / n + y = n - row - 1 + x = num % n + if row%2 == 1 { + x = n - 1 - x + } + return +} + +func snakesAndLadders(board [][]int) int { + n, sqN := len(board), len(board)*len(board) + leastRolls := make([]int, sqN) + if len(leastRolls) == 1 { + return 0 + } + + queue := make([]int, 0, sqN) + queue = append(queue, 1) + for ; len(queue) > 0; queue = queue[1:] { + cur := queue[0] + for dist := 1; dist <= 6 && cur+dist <= sqN; dist++ { + next := cur + dist + x, y := coord(n, next) + if board[y][x] != -1 { + next = board[y][x] + } + rolls := leastRolls[cur-1] + 1 + + if (next > 1 && leastRolls[next-1] == 0) || rolls < leastRolls[next-1] { + leastRolls[next-1] = rolls + if next == sqN { + return rolls + } + queue = append(queue, next) + } + } + } + + l := leastRolls[sqN-1] + if l == 0 { + return -1 + } + return 0 +} + +var _ = snakesAndLadders diff --git a/tools.go b/tools.go new file mode 100644 index 0000000..e24a421 --- /dev/null +++ b/tools.go @@ -0,0 +1,6 @@ +package leetcodego + +import ( + _ "github.com/emirpasic/gods/v2/utils" + _ "github.com/k0kubun/pp/v3" +)