From 489fa738805563993cab40c7448b7e103ad01923 Mon Sep 17 00:00:00 2001 From: Yiyang Kang Date: Mon, 9 Feb 2026 10:55:02 +0900 Subject: [PATCH] add new solutions --- go.mod | 6 +- go.sum | 6 ++ solutions/1/q110/solution.go | 36 +++++++++++ solutions/10/q1046/solution.go | 39 +++++++++++ solutions/13/q1382/solution.go | 37 +++++++++++ solutions/16/q1653/solution.go | 18 ++++++ solutions/2/q232/solution.go | 24 +++++++ solutions/20/q2073/solution.go | 17 +++++ solutions/30/q3013/solution.go | 115 +++++++++++++++++++++++++++++++++ solutions/33/q3379/solution.go | 17 +++++ solutions/36/q3634/solution.go | 33 ++++++++++ solutions/36/q3637/solution.go | 33 ++++++++++ solutions/36/q3640/solution.go | 59 +++++++++++++++++ 13 files changed, 437 insertions(+), 3 deletions(-) create mode 100644 solutions/1/q110/solution.go create mode 100644 solutions/10/q1046/solution.go create mode 100644 solutions/13/q1382/solution.go create mode 100644 solutions/16/q1653/solution.go create mode 100644 solutions/2/q232/solution.go create mode 100644 solutions/20/q2073/solution.go create mode 100644 solutions/30/q3013/solution.go create mode 100644 solutions/33/q3379/solution.go create mode 100644 solutions/36/q3634/solution.go create mode 100644 solutions/36/q3637/solution.go create mode 100644 solutions/36/q3640/solution.go diff --git a/go.mod b/go.mod index adecd14..c275cca 100644 --- a/go.mod +++ b/go.mod @@ -4,12 +4,12 @@ go 1.25.5 require ( github.com/emirpasic/gods/v2 v2.0.0-alpha - github.com/k0kubun/pp/v3 v3.5.0 + github.com/k0kubun/pp/v3 v3.5.1 ) require ( github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - golang.org/x/sys v0.39.0 // indirect - golang.org/x/text v0.32.0 // indirect + golang.org/x/sys v0.40.0 // indirect + golang.org/x/text v0.33.0 // indirect ) diff --git a/go.sum b/go.sum index 3130a0b..fe682d3 100644 --- a/go.sum +++ b/go.sum @@ -2,6 +2,8 @@ github.com/emirpasic/gods/v2 v2.0.0-alpha h1:dwFlh8pBg1VMOXWGipNMRt8v96dKAIvBeht 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/k0kubun/pp/v3 v3.5.1 h1:fS8Xt0MWVVSiKwfXeIdE0WJlktdA87/gt0Hs0+j2R2s= +github.com/k0kubun/pp/v3 v3.5.1/go.mod h1:s7qPOSp65uuilpprLJs2yDi9DNd7JGyWJPtPvDFpG9w= 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= @@ -9,5 +11,9 @@ github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= +golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= +golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE= +golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8= diff --git a/solutions/1/q110/solution.go b/solutions/1/q110/solution.go new file mode 100644 index 0000000..94b73e1 --- /dev/null +++ b/solutions/1/q110/solution.go @@ -0,0 +1,36 @@ +package q110 + +type TreeNode struct { + Val int + Left *TreeNode + Right *TreeNode +} + +func abs(a int) int { + if a < 0 { + return -a + } + return a +} + +func isBalancedInternal(node *TreeNode, lvl int) (bool, int) { + if node == nil { + return true, lvl + } + + lBal, lDpth := isBalancedInternal(node.Left, lvl+1) + rBal, rDpth := isBalancedInternal(node.Right, lvl+1) + dpth := max(lDpth, rDpth) + + if !lBal || !rBal || abs(lDpth-rDpth) > 1 { + return false, dpth + } + return true, dpth +} + +func isBalanced(root *TreeNode) bool { + ret, _ := isBalancedInternal(root, 0) + return ret +} + +var _ = isBalanced diff --git a/solutions/10/q1046/solution.go b/solutions/10/q1046/solution.go new file mode 100644 index 0000000..8249a68 --- /dev/null +++ b/solutions/10/q1046/solution.go @@ -0,0 +1,39 @@ +package q1046 + +import "container/heap" + +type IntHeap []int + +func (h *IntHeap) Len() int { return len(*h) } +func (h *IntHeap) Less(i int, j int) bool { return (*h)[i] > (*h)[j] } +func (h *IntHeap) Push(x any) { *h = append(*h, x.(int)) } +func (h *IntHeap) Swap(i int, j int) { (*h)[i], (*h)[j] = (*h)[j], (*h)[i] } + +func (h *IntHeap) Pop() any { + ret := (*h)[len(*h)-1] + *h = (*h)[:len(*h)-1] + return ret +} + +func lastStoneWeight(stones []int) int { + var st IntHeap = stones + heap.Init(&st) + + for st.Len() > 1 { + a, b := heap.Pop(&st).(int), heap.Pop(&st).(int) + rem := a - b + if rem < 0 { + rem = -rem + } + if rem > 0 { + heap.Push(&st, rem) + } + } + + if st.Len() > 0 { + return st[0] + } + return 0 +} + +var _ = lastStoneWeight diff --git a/solutions/13/q1382/solution.go b/solutions/13/q1382/solution.go new file mode 100644 index 0000000..7ae061a --- /dev/null +++ b/solutions/13/q1382/solution.go @@ -0,0 +1,37 @@ +package q1382 + +type TreeNode struct { + Val int + Left *TreeNode + Right *TreeNode +} + +func flatten(node *TreeNode, result *[]*TreeNode) { + if node == nil { + return + } + flatten(node.Left, result) + *result = append(*result, node) + flatten(node.Right, result) +} + +func reconstruct(nodes []*TreeNode) *TreeNode { + if len(nodes) == 0 { + return nil + } + mid := len(nodes) / 2 + root := nodes[mid] + root.Left = reconstruct(nodes[:mid]) + root.Right = reconstruct(nodes[mid+1:]) + + return root +} + +func balanceBST(root *TreeNode) *TreeNode { + nodes := make([]*TreeNode, 0, 128) + flatten(root, &nodes) + + return reconstruct(nodes) +} + +var _ = balanceBST diff --git a/solutions/16/q1653/solution.go b/solutions/16/q1653/solution.go new file mode 100644 index 0000000..5ccfeca --- /dev/null +++ b/solutions/16/q1653/solution.go @@ -0,0 +1,18 @@ +package q1653 + +func minimumDeletions(s string) int { + bestA, bestB := 0, 0 + + for i := range len(s) { + switch s[i] { + case 'a': + bestB++ + case 'b': + bestA, bestB = bestA+1, min(bestA, bestB) + } + } + + return min(bestA, bestB) +} + +var _ = minimumDeletions diff --git a/solutions/2/q232/solution.go b/solutions/2/q232/solution.go new file mode 100644 index 0000000..35bc078 --- /dev/null +++ b/solutions/2/q232/solution.go @@ -0,0 +1,24 @@ +package q232 + +type MyQueue struct{ data []int } + +func Constructor() MyQueue { return MyQueue{} } +func (q *MyQueue) Push(x int) { q.data = append(q.data, x) } + +func (q *MyQueue) Pop() int { + ret := q.data[0] + q.data = q.data[1:] + return ret +} + +func (q *MyQueue) Peek() int { return q.data[0] } +func (q *MyQueue) Empty() bool { return len(q.data) == 0 } + +/** + * Your MyQueue object will be instantiated and called as such: + * obj := Constructor(); + * obj.Push(x); + * param_2 := obj.Pop(); + * param_3 := obj.Peek(); + * param_4 := obj.Empty(); + */ diff --git a/solutions/20/q2073/solution.go b/solutions/20/q2073/solution.go new file mode 100644 index 0000000..9479103 --- /dev/null +++ b/solutions/20/q2073/solution.go @@ -0,0 +1,17 @@ +package q2073 + +func timeRequiredToBuy(tickets []int, k int) int { + wants := tickets[k] + + totalTime := 0 + for i := range tickets { + if i <= k { + totalTime += min(wants, tickets[i]) + } else { + totalTime += min(wants-1, tickets[i]) + } + } + return totalTime +} + +var _ = timeRequiredToBuy diff --git a/solutions/30/q3013/solution.go b/solutions/30/q3013/solution.go new file mode 100644 index 0000000..da15aff --- /dev/null +++ b/solutions/30/q3013/solution.go @@ -0,0 +1,115 @@ +package q3013 + +import ( + "container/heap" + "math" +) + +type HeapElem struct { + pos int + heapPos int +} + +type Heap struct { + data []int + h []*HeapElem + isMin bool +} + +func (h *Heap) Len() int { return len(h.h) } +func (h *Heap) TopVal() int { return h.data[h.h[0].pos] } + +func (h *Heap) Less(i int, j int) bool { + a, b := h.data[h.h[i].pos], h.data[h.h[j].pos] + if h.isMin { + return a < b + } + return a > b +} + +func (h *Heap) Push(x any) { + elem := x.(*HeapElem) + elem.heapPos = len(h.h) + h.h = append(h.h, elem) +} + +func (h *Heap) Pop() any { + ret := h.h[len(h.h)-1] + h.h = h.h[:len(h.h)-1] + ret.heapPos = -1 + return ret +} + +func (h *Heap) Swap(i int, j int) { + h.h[i].heapPos = j + h.h[j].heapPos = i + h.h[i], h.h[j] = h.h[j], h.h[i] +} + +var ( + minHpElems = make([]HeapElem, 100_000) + maxHpElems = make([]HeapElem, 100_000) + minHeapBuf = make([]*HeapElem, 100_000) + maxHeapBuf = make([]*HeapElem, 100_000) +) + +func minimumCost(nums []int, k int, dist int) int64 { + minHpElems = minHpElems[:0] + maxHpElems = maxHpElems[:0] + for i := range nums { + minHpElems = append(minHpElems, HeapElem{pos: i, heapPos: -1}) + maxHpElems = append(maxHpElems, HeapElem{pos: i, heapPos: -1}) + } + maxHeap := Heap{data: nums, h: maxHeapBuf[:0], isMin: false} + minHeap := Heap{data: nums, h: minHeapBuf[:0], isMin: true} + + sum := nums[0] + minSum := math.MaxInt + + for i := 1; i < len(nums); i++ { + remIdx := i - dist - 1 + if remIdx > 0 { + if minHpElems[remIdx].heapPos != -1 { + heap.Remove(&minHeap, minHpElems[remIdx].heapPos) + } else if maxHpElems[remIdx].heapPos != -1 { + heap.Remove(&maxHeap, maxHpElems[remIdx].heapPos) + sum -= nums[remIdx] + } + } + + if maxHeap.Len() < k-1 { + if minHeap.Len() == 0 || nums[i] <= minHeap.TopVal() { + heap.Push(&maxHeap, &maxHpElems[i]) + sum += nums[i] + } else { + heap.Push(&maxHeap, &maxHpElems[minHeap.h[0].pos]) + sum += nums[minHeap.h[0].pos] + minHeap.h[0].heapPos = -1 + minHpElems[i].heapPos = 0 + minHeap.h[0] = &minHpElems[i] + heap.Fix(&minHeap, 0) + } + + } else { + heap.Push(&minHeap, &minHpElems[i]) + minTopV, maxTopV := minHeap.TopVal(), maxHeap.TopVal() + if minTopV < maxTopV { + sum += minTopV - maxTopV + + minHeap.h[0].heapPos, maxHeap.h[0].heapPos = -1, -1 + minHeap.h[0], maxHeap.h[0] = &minHpElems[maxHeap.h[0].pos], &maxHpElems[minHeap.h[0].pos] + minHeap.h[0].heapPos, maxHeap.h[0].heapPos = 0, 0 + heap.Fix(&minHeap, 0) + heap.Fix(&maxHeap, 0) + } + } + + if maxHeap.Len() == k-1 { + minSum = min(minSum, sum) + } + } + + return int64(minSum) +} + +var _ = minimumCost diff --git a/solutions/33/q3379/solution.go b/solutions/33/q3379/solution.go new file mode 100644 index 0000000..14a4f99 --- /dev/null +++ b/solutions/33/q3379/solution.go @@ -0,0 +1,17 @@ +package q3379 + +func constructTransformedArray(nums []int) []int { + n := len(nums) + ret := make([]int, n) + for i, num := range nums { + num = (i + num) % n + if num < 0 { + num += n + } + ret[i] = nums[num] + } + + return ret +} + +var _ = constructTransformedArray diff --git a/solutions/36/q3634/solution.go b/solutions/36/q3634/solution.go new file mode 100644 index 0000000..f29eed2 --- /dev/null +++ b/solutions/36/q3634/solution.go @@ -0,0 +1,33 @@ +package q3634 + +import "slices" + +const INF int = 1<<63 - 1 + +func minRemoval(nums []int, k int) int { + slices.Sort(nums) + minRem := INF + + for i := 0; i < min(len(nums), minRem); i++ { + if i > 0 && nums[i] == nums[i-1] { + continue + } + target := nums[i] * k + + l, r := i, len(nums) + for l < r { + m := (l + r) / 2 + switch { + case nums[m] > target: + r = m + default: + l = m + 1 + } + } + + minRem = min(minRem, i+len(nums)-l) + } + return minRem +} + +var _ = minRemoval diff --git a/solutions/36/q3637/solution.go b/solutions/36/q3637/solution.go new file mode 100644 index 0000000..4774a6a --- /dev/null +++ b/solutions/36/q3637/solution.go @@ -0,0 +1,33 @@ +package q3637 + +func isTrionic(nums []int) bool { + turns := 0 + isInc := true + for i := 1; i < len(nums); i++ { + if i == 1 && nums[i] < nums[i-1] { + return false + } + + switch { + case nums[i] == nums[i-1]: + return false + case nums[i] > nums[i-1]: + if !isInc { + isInc = true + turns++ + } + case nums[i] < nums[i-1]: + if isInc { + isInc = false + turns++ + } + } + if turns > 2 { + return false + } + } + + return turns == 2 +} + +var _ = isTrionic diff --git a/solutions/36/q3640/solution.go b/solutions/36/q3640/solution.go new file mode 100644 index 0000000..b865f6d --- /dev/null +++ b/solutions/36/q3640/solution.go @@ -0,0 +1,59 @@ +package q3640 + +import "math" + +type node struct { + pos int + dir int8 +} + +const ( + NEUTRAL int8 = iota + ASCEND + DESCEND +) + +func maxSumTrionic(nums []int) int64 { + nodes := [4]node{} + pfSum := make([]int, len(nums)+1) // prefix sum + pfSum[1] = nums[0] + var maxSum = math.MinInt + + var currentDir int8 + for i := 1; i < len(nums); i++ { + switch { + case nums[i] == nums[i-1]: + currentDir = NEUTRAL + case nums[i] < nums[i-1]: + currentDir = DESCEND + default: + currentDir = ASCEND + } + + if currentDir != nodes[3].dir { + nodes[0], nodes[1], nodes[2] = nodes[1], nodes[2], nodes[3] + nodes[3] = node{ + pos: i, + dir: currentDir, + } + for j := nodes[0].pos + 1; j < nodes[1].pos; j++ { + if pfSum[j] < pfSum[nodes[0].pos] { + nodes[0].pos = j + } + } + } else { + nodes[3].pos = i + } + + pfSum[i+1] = nums[i] + pfSum[i] + + if nodes[1].dir == ASCEND && nodes[2].dir == DESCEND && nodes[3].dir == ASCEND { + curSum := pfSum[i+1] - pfSum[nodes[0].pos] + maxSum = max(curSum, maxSum) + } + } + + return int64(maxSum) +} + +var _ = maxSumTrionic