add new solutions

This commit is contained in:
Yiyang Kang 2026-02-01 14:56:08 +09:00
parent 67cad91898
commit 51975f3386
Signed by: kkyy
SSH key fingerprint: SHA256:lJSbAzC3MvrSORdvIVK6h/3g+rVKJNzM7zq0MgA9WKY
24 changed files with 933 additions and 14 deletions

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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()
}

View file

@ -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{}{}
}
}

View file

@ -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{}
}
}

View file

@ -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{}
}

View file

@ -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

View file

@ -1,20 +1,39 @@
package q1226 package q1226
func abs(i int) int { import "sync"
if i < 0 {
return -i var (
} pick = sync.Mutex{}
return i forks = [5]sync.Mutex{}
)
type DiningPhilosophers struct {
} }
func minTimeToVisitAllPoints(points [][]int) int { func (p *DiningPhilosophers) wantsToEat(
time := 0 philosopher int,
for i := 0; i < len(points)-1; i++ { pickLeftFork func(),
cur, next := points[i], points[i+1] pickRightFork func(),
dx, dy := abs(cur[0]-next[0]), abs(cur[1]-next[1]) eat func(),
time += max(dx, dy) putLeftFork func(),
} putRightFork func(),
return time ) {
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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -1 +1,22 @@
package q435 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

View file

@ -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

View file

@ -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

View file

@ -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