From 51975f338631be47348ff28d691bc18213939a43 Mon Sep 17 00:00:00 2001 From: Yiyang Kang Date: Sun, 1 Feb 2026 14:56:08 +0900 Subject: [PATCH] add new solutions --- solutions/0/q4/solution.go | 59 +++++++++++++++++ solutions/0/q84/solution.go | 29 ++++++++ solutions/1/q144/solution.go | 24 +++++++ solutions/1/q145/solution.go | 24 +++++++ solutions/11/q1114/solution.go | 35 ++++++++++ solutions/11/q1115/solution.go | 36 ++++++++++ solutions/11/q1116/solution.go | 53 +++++++++++++++ solutions/11/q1117/solution.go | 38 +++++++++++ solutions/12/q1200/solution.go | 29 ++++++++ solutions/12/q1226/solution.go | 47 +++++++++---- solutions/12/q1266/solution.go | 20 ++++++ solutions/14/q1441/solution.go | 21 ++++++ solutions/14/q1475/solution.go | 18 +++++ solutions/17/q1700/solution.go | 18 +++++ solutions/29/q2976/solution.go | 51 ++++++++++++++ solutions/29/q2977/solution.go | 96 +++++++++++++++++++++++++++ solutions/30/q3010/solution.go | 13 ++++ solutions/35/q3510/solution.go | 118 +++++++++++++++++++++++++++++++++ solutions/36/q3650/solution.go | 30 +++++++++ solutions/36/q3651/solution.go | 65 ++++++++++++++++++ solutions/4/q435/solution.go | 21 ++++++ solutions/4/q450/solution.go | 46 +++++++++++++ solutions/6/q636/solution.go | 35 ++++++++++ solutions/7/q744/solution.go | 21 ++++++ 24 files changed, 933 insertions(+), 14 deletions(-) create mode 100644 solutions/0/q4/solution.go create mode 100644 solutions/0/q84/solution.go create mode 100644 solutions/1/q144/solution.go create mode 100644 solutions/1/q145/solution.go create mode 100644 solutions/11/q1114/solution.go create mode 100644 solutions/11/q1115/solution.go create mode 100644 solutions/11/q1116/solution.go create mode 100644 solutions/11/q1117/solution.go create mode 100644 solutions/12/q1200/solution.go create mode 100644 solutions/12/q1266/solution.go create mode 100644 solutions/14/q1441/solution.go create mode 100644 solutions/14/q1475/solution.go create mode 100644 solutions/17/q1700/solution.go create mode 100644 solutions/29/q2976/solution.go create mode 100644 solutions/29/q2977/solution.go create mode 100644 solutions/30/q3010/solution.go create mode 100644 solutions/35/q3510/solution.go create mode 100644 solutions/36/q3650/solution.go create mode 100644 solutions/36/q3651/solution.go create mode 100644 solutions/4/q450/solution.go create mode 100644 solutions/6/q636/solution.go create mode 100644 solutions/7/q744/solution.go diff --git a/solutions/0/q4/solution.go b/solutions/0/q4/solution.go new file mode 100644 index 0000000..5463316 --- /dev/null +++ b/solutions/0/q4/solution.go @@ -0,0 +1,59 @@ +package q4 + +import "math" + +func findMedianSortedArrays(nums1 []int, nums2 []int) float64 { + l1, l2 := len(nums1), len(nums2) + even := (l1+l2)%2 == 0 + + if l1+l2 == 1 { + if l1 == 1 { + return float64(nums1[0]) + } + return float64(nums2[0]) + } + + // Find how many numbers `nums1` has that are to the left of the median + nLeft := (len(nums1) + len(nums2)) / 2 + l, r := max(0, nLeft-l2), min(nLeft, len(nums1))+1 + +Loop: + for l+1 < r { + m := (l + r) / 2 + p1 := m - 1 + p2 := nLeft - m - 1 + + switch { + case p2 >= 0 && p1+1 < l1 && nums2[p2] > nums1[p1+1]: + l = m + 1 + case p1 >= 0 && p2+1 < l2 && nums1[p1] > nums2[p2+1]: + r = m + default: + l = m + break Loop + } + } + + lNum, rNum := math.MinInt, math.MaxInt + p1 := l - 1 + p2 := nLeft - l - 1 + if p1 >= 0 { + lNum = max(lNum, nums1[p1]) + } + if p2 >= 0 { + lNum = max(lNum, nums2[p2]) + } + if p1+1 < l1 { + rNum = min(rNum, nums1[p1+1]) + } + if p2+1 < l2 { + rNum = min(rNum, nums2[p2+1]) + } + + if even { + return float64(lNum+rNum) / 2 + } + return float64(rNum) +} + +var _ = findMedianSortedArrays diff --git a/solutions/0/q84/solution.go b/solutions/0/q84/solution.go new file mode 100644 index 0000000..a8d38cd --- /dev/null +++ b/solutions/0/q84/solution.go @@ -0,0 +1,29 @@ +package q84 + +func largestRectangleArea(heights []int) int { + var largest int + st := make([][2]int, 0, 256) // x index, height + + for x, h := range heights { + minX := x + for len(st) > 0 && st[len(st)-1][1] > h { + largest = max(largest, st[len(st)-1][1]*(x-st[len(st)-1][0])) + minX = min(minX, st[len(st)-1][0]) + st = st[:len(st)-1] + } + + if len(st) > 0 && st[len(st)-1][1] == h { + continue + } + st = append(st, [2]int{minX, h}) + } + + for i := range st { + x, h := st[i][0], st[i][1] + largest = max(largest, h*(len(heights)-x)) + } + + return largest +} + +var _ = largestRectangleArea diff --git a/solutions/1/q144/solution.go b/solutions/1/q144/solution.go new file mode 100644 index 0000000..af1ba92 --- /dev/null +++ b/solutions/1/q144/solution.go @@ -0,0 +1,24 @@ +package q144 + +type TreeNode struct { + Val int + Left *TreeNode + Right *TreeNode +} + +func walk(node *TreeNode, ret *[]int) { + if node == nil { + return + } + *ret = append(*ret, node.Val) + walk(node.Left, ret) + walk(node.Right, ret) +} + +func preorderTraversal(root *TreeNode) []int { + ret := []int{} + walk(root, &ret) + return ret +} + +var _ = preorderTraversal diff --git a/solutions/1/q145/solution.go b/solutions/1/q145/solution.go new file mode 100644 index 0000000..dc4d8ff --- /dev/null +++ b/solutions/1/q145/solution.go @@ -0,0 +1,24 @@ +package q145 + +type TreeNode struct { + Val int + Left *TreeNode + Right *TreeNode +} + +func walk(node *TreeNode, ret *[]int) { + if node == nil { + return + } + walk(node.Left, ret) + walk(node.Right, ret) + *ret = append(*ret, node.Val) +} + +func postorderTraversal(root *TreeNode) []int { + ret := []int{} + walk(root, &ret) + return ret +} + +var _ = postorderTraversal diff --git a/solutions/11/q1114/solution.go b/solutions/11/q1114/solution.go new file mode 100644 index 0000000..3e39131 --- /dev/null +++ b/solutions/11/q1114/solution.go @@ -0,0 +1,35 @@ +package q1114 + +type Foo struct { + one, two chan struct{} +} + +func NewFoo() *Foo { + return &Foo{ + one: make(chan struct{}), + two: make(chan struct{}), + } +} + +func (f *Foo) First(printFirst func()) { + // Do not change this line + printFirst() + + close(f.one) +} + +func (f *Foo) Second(printSecond func()) { + <-f.one + + /// Do not change this line + printSecond() + + close(f.two) +} + +func (f *Foo) Third(printThird func()) { + <-f.two + + // Do not change this line + printThird() +} diff --git a/solutions/11/q1115/solution.go b/solutions/11/q1115/solution.go new file mode 100644 index 0000000..efbfde4 --- /dev/null +++ b/solutions/11/q1115/solution.go @@ -0,0 +1,36 @@ +package q1115 + +type FooBar struct { + n int + foo, bar chan struct{} +} + +func NewFooBar(n int) *FooBar { + ret := &FooBar{ + n: n, + foo: make(chan struct{}, 1), + bar: make(chan struct{}, 1), + } + ret.bar <- struct{}{} + return ret +} + +func (fb *FooBar) Foo(printFoo func()) { + for i := 0; i < fb.n; i++ { + <-fb.bar + // printFoo() outputs "foo". Do not change or remove this line. + printFoo() + + fb.foo <- struct{}{} + } +} + +func (fb *FooBar) Bar(printBar func()) { + for i := 0; i < fb.n; i++ { + <-fb.foo + // printBar() outputs "bar". Do not change or remove this line. + printBar() + + fb.bar <- struct{}{} + } +} diff --git a/solutions/11/q1116/solution.go b/solutions/11/q1116/solution.go new file mode 100644 index 0000000..1681aed --- /dev/null +++ b/solutions/11/q1116/solution.go @@ -0,0 +1,53 @@ +package q1116 + +type void struct{} + +type ZeroEvenOdd struct { + n int + c0, c1, c2 chan void +} + +func NewZeroEvenOdd(n int) *ZeroEvenOdd { + zeo := &ZeroEvenOdd{ + n: n, + c0: make(chan void, 1), + c1: make(chan void, 1), + c2: make(chan void, 1), + } + zeo.c0 <- void{} + return zeo +} + +func (z *ZeroEvenOdd) Zero(printNumber func(int)) { + for i := range z.n { + <-z.c0 + printNumber(0) + if (i+1)%2 == 0 { + z.c2 <- void{} + } else { + z.c1 <- void{} + } + } +} + +func (z *ZeroEvenOdd) Even(printNumber func(int)) { + for i := range z.n { + if (i+1)%2 != 0 { + continue + } + <-z.c2 + printNumber(i + 1) + z.c0 <- void{} + } +} + +func (z *ZeroEvenOdd) Odd(printNumber func(int)) { + for i := range z.n { + if (i+1)%2 == 0 { + continue + } + <-z.c1 + printNumber(i + 1) + z.c0 <- void{} + } +} diff --git a/solutions/11/q1117/solution.go b/solutions/11/q1117/solution.go new file mode 100644 index 0000000..e73d101 --- /dev/null +++ b/solutions/11/q1117/solution.go @@ -0,0 +1,38 @@ +package q1117 + +type void struct{} + +type H2O struct { + h, o, hRel chan void +} + +func NewH2O() *H2O { + h := &H2O{ + h: make(chan void, 2), + o: make(chan void, 2), + hRel: make(chan void, 2), + } + h.o <- void{} + return h +} + +func (h *H2O) Hydrogen(releaseHydrogen func()) { + <-h.h + // releaseHydrogen() outputs "H". Do not change or remove this line. + releaseHydrogen() + + h.hRel <- void{} // confirmation +} + +func (h *H2O) Oxygen(releaseOxygen func()) { + <-h.o + + // releaseOxygen() outputs "H". Do not change or remove this line. + releaseOxygen() + + h.h <- void{} + h.h <- void{} + <-h.hRel + <-h.hRel + h.o <- void{} +} diff --git a/solutions/12/q1200/solution.go b/solutions/12/q1200/solution.go new file mode 100644 index 0000000..c6b97df --- /dev/null +++ b/solutions/12/q1200/solution.go @@ -0,0 +1,29 @@ +package q1200 + +import ( + "math" + "slices" +) + +func minimumAbsDifference(arr []int) [][]int { + slices.Sort(arr) + + minDist := math.MaxInt + for i := range len(arr) - 1 { + minDist = min(minDist, arr[i+1]-arr[i]) + } + + ret := [][]int{} + for i := range len(arr) - 1 { + if arr[i+1]-arr[i] == minDist { + nums := []int{arr[i+1], arr[i]} + if nums[0] > nums[1] { + nums[0], nums[1] = nums[1], nums[0] + } + ret = append(ret, nums) + } + } + return ret +} + +var _ = minimumAbsDifference diff --git a/solutions/12/q1226/solution.go b/solutions/12/q1226/solution.go index 6686b35..b5e25d8 100644 --- a/solutions/12/q1226/solution.go +++ b/solutions/12/q1226/solution.go @@ -1,20 +1,39 @@ package q1226 -func abs(i int) int { - if i < 0 { - return -i - } - return i +import "sync" + +var ( + pick = sync.Mutex{} + forks = [5]sync.Mutex{} +) + +type DiningPhilosophers struct { } -func minTimeToVisitAllPoints(points [][]int) int { - time := 0 - for i := 0; i < len(points)-1; i++ { - cur, next := points[i], points[i+1] - dx, dy := abs(cur[0]-next[0]), abs(cur[1]-next[1]) - time += max(dx, dy) - } - return time +func (p *DiningPhilosophers) wantsToEat( + philosopher int, + pickLeftFork func(), + pickRightFork func(), + eat func(), + putLeftFork func(), + putRightFork func(), +) { + l, r := &forks[philosopher], &forks[(philosopher+1)%5] + + pick.Lock() + l.Lock() + r.Lock() + pick.Unlock() + + pickLeftFork() + pickRightFork() + eat() + + putLeftFork() + l.Unlock() + putRightFork() + r.Unlock() } -var _ = minTimeToVisitAllPoints +var _t = DiningPhilosophers{} +var _ = _t.wantsToEat diff --git a/solutions/12/q1266/solution.go b/solutions/12/q1266/solution.go new file mode 100644 index 0000000..31b75e6 --- /dev/null +++ b/solutions/12/q1266/solution.go @@ -0,0 +1,20 @@ +package q1266 + +func abs(i int) int { + if i < 0 { + return -i + } + return i +} + +func minTimeToVisitAllPoints(points [][]int) int { + time := 0 + for i := 0; i < len(points)-1; i++ { + cur, next := points[i], points[i+1] + dx, dy := abs(cur[0]-next[0]), abs(cur[1]-next[1]) + time += max(dx, dy) + } + return time +} + +var _ = minTimeToVisitAllPoints diff --git a/solutions/14/q1441/solution.go b/solutions/14/q1441/solution.go new file mode 100644 index 0000000..e46da81 --- /dev/null +++ b/solutions/14/q1441/solution.go @@ -0,0 +1,21 @@ +package q1441 + +const ( + PUSH = "Push" + POP = "Pop" +) + +func buildArray(target []int, n int) []string { + ret := []string{} + last := 0 + for _, num := range target { + for range num - last - 1 { + ret = append(ret, PUSH, POP) + } + ret = append(ret, PUSH) + last = num + } + return ret +} + +var _ = buildArray diff --git a/solutions/14/q1475/solution.go b/solutions/14/q1475/solution.go new file mode 100644 index 0000000..e1f2e3e --- /dev/null +++ b/solutions/14/q1475/solution.go @@ -0,0 +1,18 @@ +package q1475 + +func finalPrices(prices []int) []int { + st := make([]int, 0, 1024) + + for i := len(prices) - 1; i >= 0; i-- { + p := prices[i] + for ; len(st) > 0 && st[len(st)-1] > p; st = st[:len(st)-1] { + } + if len(st) > 0 { + prices[i] = p - st[len(st)-1] + } + st = append(st, p) + } + return prices +} + +var _ = finalPrices diff --git a/solutions/17/q1700/solution.go b/solutions/17/q1700/solution.go new file mode 100644 index 0000000..7c635a3 --- /dev/null +++ b/solutions/17/q1700/solution.go @@ -0,0 +1,18 @@ +package q1700 + +func countStudents(students []int, sandwiches []int) int { + wants := [2]int{} + for _, w := range students { + wants[w]++ + } + + for _, s := range sandwiches { + if wants[s] == 0 { + return wants[0] + wants[1] + } + wants[s]-- + } + return 0 +} + +var _ = countStudents diff --git a/solutions/29/q2976/solution.go b/solutions/29/q2976/solution.go new file mode 100644 index 0000000..d9ecf39 --- /dev/null +++ b/solutions/29/q2976/solution.go @@ -0,0 +1,51 @@ +package q2976 + +import "math" + +const INF int = math.MaxInt + +func minimumCost(source string, target string, original []byte, changed []byte, cost []int) int64 { + mat := make([][]int, 26) + for i := range mat { + mat[i] = make([]int, 26) + mat[0][i] = INF + } + for i := 1; i < 26; i++ { + copy(mat[i], mat[0]) + } + + q := make([][3]int, 0, 2*len(original)) // src, dst, cost + for i := range original { + src, dst, cst := int(original[i]-'a'), int(changed[i]-'a'), cost[i] + q = append(q, [3]int{src, dst, cst}) + mat[src][dst] = min(mat[src][dst], cst) + } + + for ; len(q) > 0; q = q[1:] { + src, dst, cst := q[0][0], q[0][1], q[0][2] + for next := range mat { + if next == src || mat[dst][next] == INF { + continue + } + nextCost := mat[dst][next] + cst + if nextCost < mat[src][next] { + mat[src][next] = nextCost + q = append(q, [3]int{src, next, nextCost}) + } + } + } + + minTotalCost := 0 + for i := range len(source) { + if source[i] != target[i] { + src, dst := source[i]-'a', target[i]-'a' + if mat[src][dst] == INF { + return -1 + } + minTotalCost += mat[src][dst] + } + } + return int64(minTotalCost) +} + +var _ = minimumCost diff --git a/solutions/29/q2977/solution.go b/solutions/29/q2977/solution.go new file mode 100644 index 0000000..0dad56b --- /dev/null +++ b/solutions/29/q2977/solution.go @@ -0,0 +1,96 @@ +package q2977 + +import "math" + +const INF int = math.MaxInt + +func minimumCost(source string, target string, original []string, changed []string, cost []int) int64 { + // Index words + words := make([]string, 0, len(original)+len(changed)) + wIdx := make(map[string]int, len(original)+len(changed)) + + addWords := func(arr []string) { + for _, word := range arr { + if _, ok := wIdx[word]; !ok { + words = append(words, word) + wIdx[word] = len(words) - 1 + } + } + } + addWords(original) + addWords(changed) + + // Calculate min cost from `original` to `changed` + mat := make([][]int, len(words)) + for i := range mat { + mat[i] = make([]int, len(words)) + mat[0][i] = INF + } + for i := 1; i < len(words); i++ { + copy(mat[i], mat[0]) + } + + q := make([][3]int, 0, 2*len(original)) // src, dst, cost + for i := range original { + src, dst, cst := wIdx[original[i]], wIdx[changed[i]], cost[i] + q = append(q, [3]int{src, dst, cst}) + mat[src][dst] = min(mat[src][dst], cst) + } + + for ; len(q) > 0; q = q[1:] { + src, dst, cst := q[0][0], q[0][1], q[0][2] + for next := range mat { + if next == src || mat[dst][next] == INF { + continue + } + nextCost := mat[dst][next] + cst + if nextCost < mat[src][next] { + mat[src][next] = nextCost + q = append(q, [3]int{src, next, nextCost}) + } + } + } + + // Calculate min cost for converting entire string + lengthsT := make(map[int]struct{}, len(original)) + for i := range original { + lengthsT[len(original[i])] = struct{}{} + } + lengths := make([]int, 0, len(lengthsT)) + for l := range lengthsT { + lengths = append(lengths, l) + } + + minCost := make([]int, len(source)+1) + for i := range minCost { + minCost[i] = INF + } + minCost[0] = 0 + + for i := 1; i < len(minCost); i++ { + if source[i-1] == target[i-1] { + minCost[i] = minCost[i-1] + } + for _, l := range lengths { + if l > i || minCost[i-l] == INF { + continue + } + srcStr, dstStr := source[i-l:i], target[i-l:i] + src, ok1 := wIdx[srcStr] + dst, ok2 := wIdx[dstStr] + if !ok1 || !ok2 || mat[src][dst] == INF { + continue + } + + minCost[i] = min(minCost[i], minCost[i-l]+mat[src][dst]) + } + } + + ret := minCost[len(minCost)-1] + if ret == INF { + return -1 + } + return int64(ret) +} + +var _ = minimumCost diff --git a/solutions/30/q3010/solution.go b/solutions/30/q3010/solution.go new file mode 100644 index 0000000..7a4bcf4 --- /dev/null +++ b/solutions/30/q3010/solution.go @@ -0,0 +1,13 @@ +package q3010 + +func minimumCost(nums []int) int { + a, b := 69, 420 + + for i := 1; i < len(nums); i++ { + a, b = min(a, b), min(max(a, b), nums[i]) + } + + return a + b + nums[0] +} + +var _ = minimumCost diff --git a/solutions/35/q3510/solution.go b/solutions/35/q3510/solution.go new file mode 100644 index 0000000..69e74a3 --- /dev/null +++ b/solutions/35/q3510/solution.go @@ -0,0 +1,118 @@ +package q3510 + +import "container/heap" + +type Node struct { + val int + prev, next *Node + arrPos, heapPos int +} + +type MinAdjSum []*Node + +func (m *MinAdjSum) Len() int { return len(*m) } + +func (m *MinAdjSum) Less(i int, j int) bool { + if (*m)[i].next == nil { + return false + } + if (*m)[j].next == nil { + return true + } + s1, p1 := (*m)[i].val+(*m)[i].next.val, (*m)[i].arrPos + s2, p2 := (*m)[j].val+(*m)[j].next.val, (*m)[j].arrPos + if s1 == s2 { + return p1 < p2 + } + return s1 < s2 +} + +func (m *MinAdjSum) Push(x any) { + elem := x.(*Node) + elem.heapPos = len(*m) + *m = append(*m, elem) +} + +func (m *MinAdjSum) Pop() any { + ret := (*m)[len(*m)-1] + (*m) = (*m)[:len(*m)-1] + return ret +} + +func (m *MinAdjSum) Swap(i int, j int) { + (*m)[i].heapPos = j + (*m)[j].heapPos = i + (*m)[i], (*m)[j] = (*m)[j], (*m)[i] +} + +func minimumPairRemoval(nums []int) int { + outOfOrder := 0 + for i := range len(nums) - 1 { + if nums[i] > nums[i+1] { + outOfOrder++ + } + } + if outOfOrder == 0 { + return 0 + } + + nodes := make([]Node, len(nums)) + hp := make(MinAdjSum, len(nums)) + for i := range nums { + nodes[i] = Node{val: nums[i], heapPos: i, arrPos: i} + hp[i] = &nodes[i] + + if i > 0 { + nodes[i].prev = &nodes[i-1] + } + if i+1 < len(nums) { + nodes[i].next = &nodes[i+1] + } + } + heap.Init(&hp) + + ops := 0 + for ; outOfOrder > 0; ops++ { + node := hp[0] + next, prev := node.next, node.prev + + heap.Remove(&hp, node.heapPos) + heap.Remove(&hp, next.heapPos) + if prev != nil { + heap.Remove(&hp, prev.heapPos) + } + + // Update outOfOrder + if next.val < node.val { + outOfOrder-- + } + if next.next != nil && next.next.val < next.val { + outOfOrder-- + } + if prev != nil && node.val < prev.val { + outOfOrder-- + } + + node.val += next.val + if prev != nil && node.val < prev.val { + outOfOrder++ + } + if next.next != nil && next.next.val < node.val { + outOfOrder++ + } + + // Update links & fix heap + node.next = next.next + if next.next != nil { + next.next.prev = node + } + + heap.Push(&hp, node) + if prev != nil { + heap.Push(&hp, prev) + } + } + return ops +} + +var _ = minimumPairRemoval diff --git a/solutions/36/q3650/solution.go b/solutions/36/q3650/solution.go new file mode 100644 index 0000000..d3c24a3 --- /dev/null +++ b/solutions/36/q3650/solution.go @@ -0,0 +1,30 @@ +package q3650 + +func minCost(n int, edges [][]int) int { + connections := make([][][2]int, n) + for i := range edges { + f, t, w := edges[i][0], edges[i][1], edges[i][2] + connections[f] = append(connections[f], [2]int{t, w}) + connections[t] = append(connections[t], [2]int{f, w * 2}) + } + minCost := make([]int, n) + minCost[0] = 1 + + queue := make([]int, 0, 1024) + queue = append(queue, 0) + for ; len(queue) > 0; queue = queue[1:] { + node := queue[0] + + for i := range connections[node] { + next, cost := connections[node][i][0], connections[node][i][1] + if minCost[next] == 0 || minCost[node]+cost < minCost[next] { + minCost[next] = minCost[node] + cost + queue = append(queue, next) + } + } + } + + return minCost[n-1] - 1 +} + +var _ = minCost diff --git a/solutions/36/q3651/solution.go b/solutions/36/q3651/solution.go new file mode 100644 index 0000000..484d2c2 --- /dev/null +++ b/solutions/36/q3651/solution.go @@ -0,0 +1,65 @@ +package q3651 + +import ( + "math" + "slices" +) + +func minCost(grid [][]int, k int) int { + w, h := len(grid[0]), len(grid) + gridVal := func(coord int) int { return grid[coord/w][coord%w] } + + sortedCoords := make([]int, w*h) + for i := range sortedCoords { + sortedCoords[i] = (i) + } + slices.SortFunc(sortedCoords, func(a, b int) int { return gridVal(a) - gridVal(b) }) + + cache := make([]int32, w*h) + prevMinCosts := make([]int32, len(sortedCoords)) + + for tele := range k + 1 { + // Precompute min costs + if tele > 0 { + var curMin int32 = math.MaxInt32 + i, j := 0, 0 + for i < len(sortedCoords) { + curMin = min(curMin, cache[sortedCoords[i]]) + + i++ + for j < i && (i == len(sortedCoords) || gridVal(sortedCoords[i]) > gridVal(sortedCoords[j])) { + prevMinCosts[sortedCoords[j]] = curMin + j++ + } + } + } + + for r := h - 1; r >= 0; r-- { + for c := w - 1; c >= 0; c-- { + if r == h-1 && c == w-1 { + continue + } + + var val int32 = math.MaxInt32 + if r+1 < h { + val = min(val, cache[(r+1)*w+c]+int32(grid[r+1][c])) + } + if c+1 < w { + val = min(val, cache[r*w+c+1]+int32(grid[r][c+1])) + } + + if tele == 0 { + cache[r*w+c] = val + continue + } + + // Find min cost with teleports + cache[r*w+c] = min(val, prevMinCosts[r*w+c]) + } + } + } + + return int(cache[0]) +} + +var _ = minCost diff --git a/solutions/4/q435/solution.go b/solutions/4/q435/solution.go index 737290c..f0e68f3 100644 --- a/solutions/4/q435/solution.go +++ b/solutions/4/q435/solution.go @@ -1 +1,22 @@ package q435 + +import ( + "math" + "slices" +) + +func eraseOverlapIntervals(intervals [][]int) int { + slices.SortFunc(intervals, func(a, b []int) int { return a[1] - b[1] }) + + keep := 0 + end := math.MinInt + for i := range intervals { + if intervals[i][0] >= end { + end = intervals[i][1] + keep++ + } + } + return len(intervals) - keep +} + +var _ = eraseOverlapIntervals diff --git a/solutions/4/q450/solution.go b/solutions/4/q450/solution.go new file mode 100644 index 0000000..d5b280f --- /dev/null +++ b/solutions/4/q450/solution.go @@ -0,0 +1,46 @@ +package q450 + +type TreeNode struct { + Val int + Left *TreeNode + Right *TreeNode +} + +func del(node *TreeNode) *TreeNode { + if node == nil || node.Left == nil && node.Right == nil { + return nil // is leaf + } + if node.Left == nil { + return node.Right + } + if node.Right == nil { + return node.Left + } + + p := node.Left + for p.Right != nil { + p = p.Right + } + p.Right = node.Right + return node.Left +} + +func findAndDel(node **TreeNode, key int) { + if *node == nil { + return + } + if (**node).Val == key { + *node = del(*node) + } else if key < (**node).Val { + findAndDel(&(**node).Left, key) + } else { + findAndDel(&(**node).Right, key) + } +} + +func deleteNode(root *TreeNode, key int) *TreeNode { + findAndDel(&root, key) + return root +} + +var _ = deleteNode diff --git a/solutions/6/q636/solution.go b/solutions/6/q636/solution.go new file mode 100644 index 0000000..f46e6d1 --- /dev/null +++ b/solutions/6/q636/solution.go @@ -0,0 +1,35 @@ +package q636 + +import ( + "strconv" + "strings" +) + +func exclusiveTime(n int, logs []string) []int { + ret := make([]int, n) + stack := make([][3]int, 0, 256) // proc id, start time, child exec time + + for i := range logs { + fields := strings.FieldsFunc(logs[i], func(r rune) bool { return r == ':' }) + id, _ := strconv.ParseInt(fields[0], 10, strconv.IntSize) + action := fields[1] + curTime, _ := strconv.ParseInt(fields[2], 10, strconv.IntSize) + + switch action { + case "start": + stack = append(stack, [3]int{int(id), int(curTime), 0}) + case "end": + i := len(stack) - 1 + id, stT, chT := stack[i][0], stack[i][1], stack[i][2] + ret[id] += int(curTime) - stT + 1 - chT + + if len(stack) > 1 { + stack[i-1][2] += int(curTime) - stT + 1 + } + stack = stack[:len(stack)-1] // pop + } + } + return ret +} + +var _ = exclusiveTime diff --git a/solutions/7/q744/solution.go b/solutions/7/q744/solution.go new file mode 100644 index 0000000..e50e604 --- /dev/null +++ b/solutions/7/q744/solution.go @@ -0,0 +1,21 @@ +package q744 + +func nextGreatestLetter(letters []byte, target byte) byte { + l, r := 0, len(letters) + for l < r { + m := (l + r) / 2 + + if letters[m] <= target { + l = m + 1 + } else { + r = m + } + } + + if l == len(letters) { + l = 0 + } + return letters[l] +} + +var _ = nextGreatestLetter