add new solutions

This commit is contained in:
kanna5 2026-01-05 16:48:03 +09:00
parent 886b5e0a8e
commit 67cad91898
Signed by: kkyy
GPG key ID: 06332F3965E9B0CF
47 changed files with 1549 additions and 1 deletions

View file

@ -0,0 +1,52 @@
package q23
import "container/heap"
type ListNode struct {
Val int
Next *ListNode
}
type MinNodeHp []*ListNode
func (m *MinNodeHp) Len() int { return len(*m) }
func (m *MinNodeHp) Less(i int, j int) bool { return (*m)[i].Val < (*m)[j].Val }
func (m *MinNodeHp) Push(x any) { *m = append(*m, x.(*ListNode)) }
func (m *MinNodeHp) Swap(i int, j int) { (*m)[i], (*m)[j] = (*m)[j], (*m)[i] }
func (m *MinNodeHp) Pop() any {
*m = (*m)[:len(*m)-1]
return nil
}
var _ heap.Interface = &MinNodeHp{}
func mergeKLists(lists []*ListNode) *ListNode {
hp := make(MinNodeHp, 0, len(lists))
for i := range lists {
if lists[i] != nil {
hp = append(hp, lists[i])
}
}
heap.Init(&hp)
head := &ListNode{}
tail := head
for len(hp) > 0 {
tail.Next = hp[0]
tail = tail.Next
hp[0] = hp[0].Next
if hp[0] == nil {
heap.Remove(&hp, 0)
} else {
heap.Fix(&hp, 0)
}
}
tail.Next = nil
return head.Next
}
var _ = mergeKLists

View file

@ -0,0 +1,15 @@
package q62
func uniquePaths(m int, n int) int {
buf := make([]int, n)
buf[0] = 1
for range m {
for c := 1; c < n; c++ {
buf[c] += buf[c-1]
}
}
return buf[n-1]
}
var _ = uniquePaths

View file

@ -0,0 +1,25 @@
package q94
type TreeNode struct {
Val int
Left *TreeNode
Right *TreeNode
}
func traversal(node *TreeNode, ret *[]int) {
if node == nil {
return
}
traversal(node.Left, ret)
*ret = append(*ret, node.Val)
traversal(node.Right, ret)
}
func inorderTraversal(root *TreeNode) []int {
// left, center, right
ret := []int{}
traversal(root, &ret)
return ret
}
var _ = inorderTraversal

View file

@ -0,0 +1,32 @@
package q142
type ListNode struct {
Val int
Next *ListNode
}
func detectCycle(head *ListNode) *ListNode {
p1, p2 := head, head
for p1 != nil && p2 != nil {
p1 = p1.Next
p2 = p2.Next
if p2 != nil {
p2 = p2.Next
}
if p1 == p2 {
break
}
}
if p2 == nil {
return nil
}
p1 = head
for p1 != p2 {
p1 = p1.Next
p2 = p2.Next.Next
}
return p1
}
var _ = detectCycle

View file

@ -0,0 +1,26 @@
package q1004
func longestOnes(nums []int, k int) int {
flipped := 0
curLen, maxLen := 0, 0
tail := 0
for i := range nums {
curLen++
if nums[i] == 0 {
flipped++
for flipped > k {
if nums[tail] == 0 {
flipped--
}
tail++
curLen--
}
}
maxLen = max(maxLen, curLen)
}
return maxLen
}
var _ = longestOnes

View file

@ -0,0 +1,24 @@
package q1143
// Note: Can be compressed to only len(text1) extra space.
func longestCommonSubsequence(text1 string, text2 string) int {
commonSeqLen := make([][]int, len(text1)+1)
for i := range commonSeqLen {
commonSeqLen[i] = make([]int, len(text2)+1)
}
for i1 := 1; i1 <= len(text1); i1++ {
for i2 := 1; i2 <= len(text2); i2++ {
if text1[i1-1] == text2[i2-1] {
commonSeqLen[i1][i2] = commonSeqLen[i1-1][i2-1] + 1
} else {
commonSeqLen[i1][i2] = max(commonSeqLen[i1-1][i2], commonSeqLen[i1][i2-1])
}
}
}
return commonSeqLen[len(text1)][len(text2)]
}
var _ = longestCommonSubsequence

View file

@ -0,0 +1,38 @@
package q1268
import "slices"
func prefixSearch(products []string, prefix string) []string {
ret := make([]string, 0, 3)
pfLen := len(prefix)
l, r := 0, len(products)
for l < r {
m := (l + r) / 2
if products[m][:min(len(products[m]), pfLen)] >= prefix {
r = m
} else {
l = m + 1
}
}
for ; l < len(products) && len(products[l]) >= pfLen && products[l][:pfLen] == prefix; l++ {
ret = append(ret, products[l])
if len(ret) == 3 {
break
}
}
return ret
}
func suggestedProducts(products []string, searchWord string) [][]string {
slices.Sort(products)
ret := make([][]string, 0, len(searchWord))
for i := range len(searchWord) {
ret = append(ret, prefixSearch(products, searchWord[:i+1]))
}
return ret
}
var _ = suggestedProducts

View file

@ -0,0 +1,51 @@
package q1292
func pfSum(mat [][]int) [][]int {
w, h := len(mat[0])+1, len(mat)+1
pfs := make([][]int, h)
for i := range pfs {
pfs[i] = make([]int, w)
}
for y := 1; y < h; y++ {
for x := 1; x < w; x++ {
pfs[y][x] = mat[y-1][x-1] + pfs[y][x-1] + pfs[y-1][x] - pfs[y-1][x-1]
}
}
return pfs
}
func sumOfSquare(pfs [][]int, x, y, w int) int {
return pfs[y+w][x+w] - pfs[y][x+w] - pfs[y+w][x] + pfs[y][x]
}
func hasSquare(pfs [][]int, edgeLen, threshold int) bool {
w, h := len(pfs[0])-1, len(pfs)-1
for y := range h - edgeLen + 1 {
for x := range w - edgeLen + 1 {
if sumOfSquare(pfs, x, y, edgeLen) <= threshold {
return true
}
}
}
return false
}
func maxSideLength(mat [][]int, threshold int) int {
pfs := pfSum(mat)
w, h := len(pfs[0]), len(pfs)
maxAllowed := min(w, h)
l, r := 0, maxAllowed+1
for l+1 < r {
m := (l + r) / 2
if hasSquare(pfs, m, threshold) {
l = m
} else {
r = m
}
}
return l
}
var _ = maxSideLength

View file

@ -0,0 +1,28 @@
package q1318
func minFlips(a int, b int, c int) int {
aorb := a | b
flips := 0
p := 1
for p <= aorb || p <= c {
switch {
case c|p == c && aorb|p != aorb:
flips++ // c has the bit
case c|p != c && aorb|p == aorb:
if a|p == a {
flips++ // a has the bit
}
if b|p == b {
flips++ // b has the bit
}
}
p <<= 1
}
return flips
}
var _ = minFlips

View file

@ -0,0 +1,34 @@
package q1372
type TreeNode struct {
Val int
Left *TreeNode
Right *TreeNode
}
func zigZagLen(node *TreeNode, isLeft bool, curLen int) int {
if node == nil {
return 0
}
var l, r int
if isLeft {
l = zigZagLen(node.Left, true, 1)
r = zigZagLen(node.Right, false, curLen+1)
} else {
l = zigZagLen(node.Left, true, curLen+1)
r = zigZagLen(node.Right, false, 1)
}
return max(curLen, l, r)
}
func longestZigZag(root *TreeNode) int {
if root == nil {
return 0
}
return max(
zigZagLen(root.Left, true, 1),
zigZagLen(root.Right, false, 1),
)
}
var _ = longestZigZag

View file

@ -0,0 +1,28 @@
package q1448
import "math"
type TreeNode struct {
Val int
Left *TreeNode
Right *TreeNode
}
func gn(node *TreeNode, curMax int) int {
if node == nil {
return 0
}
self := 0
if node.Val >= curMax {
self = 1
}
curMax = max(curMax, node.Val)
return self + gn(node.Left, curMax) + gn(node.Right, curMax)
}
func goodNodes(root *TreeNode) int {
return gn(root, math.MinInt)
}
var _ = goodNodes

View file

@ -0,0 +1,27 @@
package q1456
func isVowel(b byte) bool {
switch b {
case 'a', 'e', 'i', 'o', 'u':
return true
}
return false
}
func maxVowels(s string, k int) int {
maxV := 0
curr := 0
for i := range len(s) {
if isVowel(s[i]) {
curr++
}
if i >= k && isVowel(s[i-k]) {
curr--
}
maxV = max(curr, maxV)
}
return maxV
}
var _ = maxVowels

View file

@ -0,0 +1,67 @@
package q1466
import "math"
func walk(connections [][2][]int, minFlips []int32, node int) {
mf := minFlips[node]
// Walk no-flip-needed
for _, n := range connections[node][1] {
if mf < minFlips[n] {
minFlips[n] = mf
walk(connections, minFlips, n)
}
}
// Walk flip-needed
for _, n := range connections[node][0] {
if mf+1 < minFlips[n] {
minFlips[n] = mf + 1
walk(connections, minFlips, n)
}
}
}
func collect(connections [][2][]int, minFlips []int32, node int, visited []bool) int32 {
mf := minFlips[node]
var sum int32
for _, n := range connections[node][1] {
if !visited[n] && mf == minFlips[n] {
visited[n] = true
sum += collect(connections, minFlips, n, visited) - mf
}
}
for _, n := range connections[node][0] {
if !visited[n] && mf+1 == minFlips[n] {
visited[n] = true
sum += collect(connections, minFlips, n, visited) - mf
}
}
return sum + mf
}
func minReorder(n int, connections [][]int) int {
conns := make([][2][]int, n)
for i := range connections {
from, to := connections[i][0], connections[i][1]
conns[from][0] = append(conns[from][0], to)
conns[to][1] = append(conns[to][1], from)
}
minFlips := make([]int32, n) // minimum flips to reach node n
minFlips[0] = math.MaxInt32
for i := 1; i < len(minFlips); i *= 2 {
copy(minFlips[i:], minFlips[:i])
}
minFlips[0] = 0
walk(conns, minFlips, 0)
visited := make([]bool, n)
return int(collect(conns, minFlips, 0, visited))
}
var _ = minReorder

View file

@ -0,0 +1,24 @@
package q1493
func longestSubarray(nums []int) int {
prev, cur := 0, 0
longest := 0
has0 := false
for _, a := range nums {
if a == 1 {
cur++
}
longest = max(longest, prev+cur)
if a == 0 {
prev, cur = cur, 0
has0 = true
}
}
if !has0 {
longest--
}
return longest
}
var _ = longestSubarray

View file

@ -0,0 +1,30 @@
package q1657
import "slices"
func closeStrings(word1 string, word2 string) bool {
if len(word1) != len(word2) {
return false
}
charCount1, charCount2 := make([]int, 26), make([]int, 26)
for i := range len(word1) {
charCount1[word1[i]-'a']++
charCount2[word2[i]-'a']++
}
for i := range charCount1 {
if charCount1[i] == 0 && charCount2[i] != 0 {
return false
}
if charCount1[i] != 0 && charCount2[i] == 0 {
return false
}
}
slices.Sort(charCount1)
slices.Sort(charCount2)
return slices.Equal(charCount1, charCount2)
}
var _ = closeStrings

View file

@ -0,0 +1,26 @@
package q1679
import "slices"
func maxOperations(nums []int, k int) int {
slices.Sort(nums)
nOps := 0
l, r := 0, len(nums)-1
for l < r {
sum := nums[l] + nums[r]
switch {
case sum == k:
nOps++
l++
r--
case sum > k:
r--
default:
l++
}
}
return nOps
}
var _ = maxOperations

View file

@ -0,0 +1,16 @@
package q1877
import "slices"
func minPairSum(nums []int) int {
slices.Sort(nums)
n := len(nums)
maxSum := 0
for i := range n / 2 {
maxSum = max(maxSum, nums[i]+nums[n-1-i])
}
return maxSum
}
var _ = minPairSum

View file

@ -0,0 +1,59 @@
package q1895
func isMagicSq(grid [][]int, x, y, w int) bool {
diag1Sum := 0
diag2Sum := 0
for i := range w {
ax, ay := x+i, y+i
diag1Sum += grid[ay][ax]
ax = x + w - 1 - i
diag2Sum += grid[ay][ax]
}
if diag1Sum != diag2Sum {
return false
}
// horizontal
for dy := range w {
sum := 0
for dx := range w {
sum += grid[y+dy][x+dx]
}
if sum != diag1Sum {
return false
}
}
// vertical
for dx := range w {
sum := 0
for dy := range w {
sum += grid[y+dy][x+dx]
}
if sum != diag1Sum {
return false
}
}
return true
}
func largestMagicSquare(grid [][]int) int {
k := 1
gW, gH := len(grid[0]), len(grid)
Outer:
for w := 2; w <= min(gW, gH); w++ {
for y := range gH - w + 1 {
for x := range gW - w + 1 {
if isMagicSq(grid, x, y, w) {
k = w
continue Outer
}
}
}
}
return k
}
var _ = largestMagicSquare

View file

@ -0,0 +1,40 @@
package q1926
const (
EMPTY byte = '.'
WALL byte = '+'
)
func nearestExit(maze [][]byte, entrance []int) int {
queue := make([][3]int, 0, len(maze)) // row, col, step
queue = append(queue, [3]int{entrance[0], entrance[1], 0})
maze[entrance[0]][entrance[1]] = WALL // mark as visited
var add = func(r, c, s int) bool {
if r < 0 || c < 0 || r >= len(maze) || c >= len(maze[0]) || maze[r][c] != EMPTY {
return false
}
if r == 0 || c == 0 || r == len(maze)-1 || c == len(maze[0])-1 {
return true // found
}
maze[r][c] = WALL
queue = append(queue, [3]int{r, c, s})
return false
}
for ; len(queue) > 0; queue = queue[1:] {
cur := queue[0]
r, c, s := cur[0], cur[1], cur[2]
if add(r, c+1, s+1) ||
add(r, c-1, s+1) ||
add(r+1, c, s+1) ||
add(r-1, c, s+1) {
return s + 1
}
}
return -1
}
var _ = nearestExit

View file

@ -0,0 +1,17 @@
package q1984
import (
"math"
"slices"
)
func minimumDifference(nums []int, k int) int {
slices.Sort(nums)
minDiff := math.MaxInt
for i := 0; i < len(nums)-k+1; i++ {
minDiff = min(nums[i+k-1]-nums[i], minDiff)
}
return minDiff
}
var _ = minimumDifference

View file

@ -0,0 +1,37 @@
package q216
// k numbers sum up to n
func calc(k int, buf []int, offset int, remSum int, ret [][]int) [][]int {
if offset == k-1 && remSum > 0 && remSum < 10 {
buf[offset] = remSum
cp := make([]int, len(buf))
copy(cp, buf)
return append(ret, cp)
}
remK := k - offset
minI := 1
if offset > 0 {
minI = buf[offset-1] + 1
}
maxI := 9 - remK + 1
for i := minI; i <= maxI; i++ {
minSum := (i + i + remK - 1) * remK / 2
maxSum := (19 - remK) * remK / 2
if remSum < minSum || remSum > maxSum {
continue
}
buf[offset] = i
ret = calc(k, buf, offset+1, remSum-i, ret)
}
return ret
}
func combinationSum3(k int, n int) [][]int {
return calc(k, make([]int, k), 0, n, [][]int{})
}
var _ = combinationSum3

View file

@ -0,0 +1,22 @@
package q2095
type ListNode struct {
Val int
Next *ListNode
}
func deleteMiddle(head *ListNode) *ListNode {
stub := &ListNode{Next: head}
fast, slow := stub, stub
for fast.Next != nil && fast.Next.Next != nil {
fast = fast.Next.Next
slow = slow.Next
}
if slow.Next != nil {
slow.Next = slow.Next.Next
}
return stub.Next
}
var _ = deleteMiddle

View file

@ -0,0 +1,27 @@
package q2130
import "math"
type ListNode struct {
Val int
Next *ListNode
}
var arr = []int{}
func pairSum(head *ListNode) int {
arr = arr[:0]
for p := head; p != nil; p = p.Next {
arr = append(arr, p.Val)
}
maxSum := math.MinInt
l, r := 0, len(arr)-1
for l < r {
maxSum = max(maxSum, arr[l]+arr[r])
l++
r--
}
return maxSum
}
var _ = pairSum

View file

@ -0,0 +1,32 @@
package q2300
import "slices"
func nGte(arr []int, target int) int {
l, r := 0, len(arr)
for l < r {
m := (l + r) / 2
if arr[m] >= target {
r = m
} else {
l = m + 1
}
}
return len(arr) - l
}
func successfulPairs(spells []int, potions []int, success int64) []int {
slices.Sort(potions)
for i := range spells {
pow := spells[i]
want := int(success) / pow
if pow*want < int(success) {
want++
}
spells[i] = nGte(potions, want)
}
return spells
}
var _ = successfulPairs

View file

@ -0,0 +1,55 @@
package q2336
import "container/heap"
type MinHeap []int
func (m *MinHeap) Len() int { return len(*m) }
func (m *MinHeap) Less(i int, j int) bool { return (*m)[i] < (*m)[j] }
func (m *MinHeap) Push(x any) { *m = append(*m, x.(int)) }
func (m *MinHeap) Swap(i int, j int) { (*m)[i], (*m)[j] = (*m)[j], (*m)[i] }
func (m *MinHeap) Pop() any {
ret := (*m)[len(*m)-1]
*m = (*m)[:len(*m)-1]
return ret
}
type SmallestInfiniteSet struct {
head int
added MinHeap
}
func Constructor() SmallestInfiniteSet {
return SmallestInfiniteSet{
head: 1,
added: MinHeap{},
}
}
func (s *SmallestInfiniteSet) PopSmallest() int {
if s.added.Len() > 0 {
top := s.added[0]
for s.added.Len() > 0 && s.added[0] == top {
heap.Pop(&s.added)
}
return top
} else {
s.head++
return s.head - 1
}
}
func (s *SmallestInfiniteSet) AddBack(num int) {
if num >= s.head {
return
}
heap.Push(&s.added, num)
}
/**
* Your SmallestInfiniteSet object will be instantiated and called as such:
* obj := Constructor();
* param_1 := obj.PopSmallest();
* obj.AddBack(num);
*/

View file

@ -0,0 +1,39 @@
package q2352
import "strings"
func index(grid [][]int, col bool, i int) string {
b := strings.Builder{}
b.Grow(len(grid) * 3)
for j := range grid {
var num int
switch {
case col: // ith col
num = grid[j][i]
default: // ith row
num = grid[i][j]
}
for range 3 {
b.WriteByte(byte(num % 256))
num >>= 8
}
}
return b.String()
}
func equalPairs(grid [][]int) int {
idx := make(map[string]int, len(grid))
nEq := 0
for row := range grid {
s := index(grid, false, row)
idx[s]++
}
for col := range grid {
s := index(grid, true, col)
nEq += idx[s]
}
return nEq
}
var _ = equalPairs

View file

@ -73,5 +73,4 @@ func mostBooked(n int, meetings [][]int) int {
return mbIdx
}
var _ heap.Interface = &Rooms{}
var _ = mostBooked

View file

@ -0,0 +1,62 @@
package q2462
import "container/heap"
type CustomMinHeap struct {
data []int
less func(a, b int) bool
}
func (c *CustomMinHeap) Len() int { return len(c.data) }
func (c *CustomMinHeap) Less(i int, j int) bool { return c.less(c.data[i], c.data[j]) }
func (c *CustomMinHeap) Push(x any) { c.data = append(c.data, x.(int)) }
func (c *CustomMinHeap) Swap(i int, j int) { c.data[i], c.data[j] = c.data[j], c.data[i] }
func (c *CustomMinHeap) Pop() any {
last := c.data[len(c.data)-1]
c.data = c.data[:len(c.data)-1]
return last
}
func totalCost(costs []int, k int, candidates int) int64 {
lessFn := func(i, j int) bool {
if costs[i] == costs[j] {
return i < j
}
return costs[i] < costs[j]
}
indices := make([]int, 0, 2*candidates)
l, r := 0, len(costs)-1
for l <= r && l < candidates {
indices = append(indices, l)
if l < r {
indices = append(indices, r)
}
l++
r--
}
hp := &CustomMinHeap{data: indices, less: lessFn}
heap.Init(hp)
cost := 0
for range k {
i := heap.Pop(hp).(int)
cost += costs[i]
if l <= r {
switch {
case i < l:
heap.Push(hp, l)
l++
default:
heap.Push(hp, r)
r--
}
}
}
return int64(cost)
}
var _ = totalCost

View file

@ -0,0 +1,58 @@
package q2542
import (
"container/heap"
"slices"
)
type minHeap struct {
data []int
lessFn func(i, j int) bool
}
func (m *minHeap) Len() int { return len(m.data) }
func (m *minHeap) Less(i int, j int) bool { return m.lessFn(m.data[i], m.data[j]) }
func (m *minHeap) Push(x any) { m.data = append(m.data, x.(int)) }
func (m *minHeap) Swap(i int, j int) { m.data[i], m.data[j] = m.data[j], m.data[i] }
func (m *minHeap) Pop() any {
last := m.data[len(m.data)-1]
m.data = m.data[:len(m.data)-1]
return last
}
func maxScore(nums1 []int, nums2 []int, k int) int64 {
indices := make([]int, len(nums1))
for i := range indices {
indices[i] = i
}
slices.SortFunc(indices, func(a, b int) int { return nums2[b] - nums2[a] })
mh := &minHeap{
data: make([]int, 0, k),
lessFn: func(a int, b int) bool { return nums1[a] < nums1[b] },
}
sum := 0
for i := range k {
mh.data = append(mh.data, indices[i])
sum += nums1[indices[i]]
}
heap.Init(mh)
maxScore := sum * nums2[indices[k-1]]
for i := k; i < len(nums1); i++ {
realI := indices[i]
n1, n2 := nums1[realI], nums2[realI]
if nums1[mh.data[0]] < n1 {
sum = sum - nums1[mh.data[0]] + n1
mh.data[0] = realI
heap.Fix(mh, 0)
maxScore = max(maxScore, sum*n2)
}
}
return int64(maxScore)
}
var _ = maxScore

View file

@ -0,0 +1,29 @@
package q328
type ListNode struct {
Val int
Next *ListNode
}
func oddEvenList(head *ListNode) *ListNode {
odd := &ListNode{}
even := &ListNode{}
pO, pE := odd, even
i := 0
for p := head; p != nil; p = p.Next {
i++
if i%2 == 0 {
pE.Next = p
pE = p
} else {
pO.Next = p
pO = p
}
}
pE.Next = nil
pO.Next = even.Next
return odd.Next
}
var _ = oddEvenList

View file

@ -0,0 +1,24 @@
package q334
import "math"
func increasingTriplet(nums []int) bool {
if len(nums) < 3 {
return false
}
first, second := math.MaxInt, math.MaxInt
for _, x := range nums {
if x <= first {
first = x
} else if x <= second {
second = x
} else {
return true
}
}
return false
}
var _ = increasingTriplet

View file

@ -0,0 +1,41 @@
package q394
import "strings"
func decode(s string) (int, string) {
advanced := 0
number := 0
buf := strings.Builder{}
Loop:
for advanced < len(s) {
advanced++
cur := s[advanced-1]
switch {
case cur >= '0' && cur <= '9':
number = 10*number + int(cur-'0')
case cur == '[':
adv, child := decode(s[advanced:])
advanced += adv
for range number {
buf.WriteString(child)
}
number = 0
case cur == ']':
break Loop
default:
buf.WriteByte(cur)
}
}
return advanced, buf.String()
}
func decodeString(s string) string {
_, ret := decode(s)
return ret
}
var _ = decodeString

View file

@ -0,0 +1,19 @@
package q3314
func minBitwiseArray(nums []int) []int {
for i := range nums {
if nums[i]%2 == 0 {
nums[i] = -1
continue
}
p := 1
for nums[i]|(1<<p) == nums[i] {
p++
}
nums[i] -= 1 << (p - 1)
}
return nums
}
var _ = minBitwiseArray

View file

@ -0,0 +1,18 @@
package q3315
func minBitwiseArray(nums []int) []int {
for i, num := range nums {
if num == 2 {
nums[i] = -1
continue
}
t := 1
for ; num|(t<<1) == num; t <<= 1 {
}
nums[i] = num - t
}
return nums
}
var _ = minBitwiseArray

View file

@ -0,0 +1,36 @@
package q3507
import "math"
func minimumPairRemoval(nums []int) int {
var nOp int
var op = func() bool {
minP, minSum := 0, math.MaxInt
sorted := true
for i := range len(nums) - 1 {
sum := nums[i] + nums[i+1]
if sum < minSum {
minSum = sum
minP = i
}
if sorted && nums[i+1] < nums[i] {
sorted = false
}
}
if sorted {
return false
}
nums[minP] += nums[minP+1]
copy(nums[minP+1:], nums[minP+2:])
nums = nums[:len(nums)-1]
return true
}
for op() {
nOp++
}
return nOp
}
var _ = minimumPairRemoval

View file

@ -0,0 +1,36 @@
package q437
type TreeNode struct {
Val int
Left *TreeNode
Right *TreeNode
}
func count(node *TreeNode, prefix []int, target int) int {
if node == nil {
return 0
}
if len(prefix) > 0 {
prefix = append(prefix, node.Val+prefix[len(prefix)-1])
} else {
prefix = append(prefix, node.Val)
}
cnt := 0
for i := range len(prefix) - 1 {
if prefix[len(prefix)-1]-prefix[i] == target {
cnt++
}
}
if prefix[len(prefix)-1] == target {
cnt++
}
return cnt + count(node.Left, prefix, target) + count(node.Right, prefix, target)
}
func pathSum(root *TreeNode, targetSum int) int {
return count(root, nil, targetSum)
}
var _ = pathSum

View file

@ -0,0 +1,39 @@
package q443
func compress(chars []byte) int {
seqLen := 0
char := chars[0]
p := 1
writeNumber := func(num int) {
i := 1
for ; i*10 <= num; i *= 10 {
}
for ; i > 0; i /= 10 {
chars[p] = byte(num/i) + '0'
p++
num %= i
}
}
for _, c := range chars {
if c == char {
seqLen++
} else {
char = c
if seqLen > 1 {
writeNumber(seqLen)
}
seqLen = 1
chars[p] = char
p++
}
}
if seqLen > 1 {
writeNumber(seqLen)
}
return p
}
var _ = compress

View file

@ -0,0 +1,25 @@
package q547
func walk(graph [][]int, i int, seen []bool) {
for j := range graph {
if graph[i][j] == 1 && !seen[j] {
seen[j] = true
walk(graph, j, seen)
}
}
}
func findCircleNum(isConnected [][]int) int {
seen := make([]bool, len(isConnected))
provinces := 0
for i := range len(isConnected) {
if !seen[i] {
walk(isConnected, i, seen)
provinces++
}
}
return provinces
}
var _ = findCircleNum

View file

@ -0,0 +1,51 @@
package q649
func predictPartyVictory(senate string) string {
n := len(senate)
revoked := make([]bool, n)
rRevoke, dRevoke := 0, 0
rRem, dRem := 0, 0
for i := range n {
switch senate[i] {
case 'R':
rRem++
case 'D':
dRem++
}
}
for i := 0; rRem > 0 && dRem > 0; i = (i + 1) % n {
if revoked[i] {
continue
}
switch senate[i] {
case 'R':
if rRevoke > 0 {
rRevoke--
rRem--
revoked[i] = true
} else {
dRevoke++
}
case 'D':
if dRevoke > 0 {
dRevoke--
dRem--
revoked[i] = true
} else {
rRevoke++
}
}
}
if rRem == 0 {
return "Dire"
} else {
return "Radiant"
}
}
var _ = predictPartyVictory

View file

@ -0,0 +1,33 @@
package q714
// Note: could be done faster with dynamic programming
func maxProfit(prices []int, fee int) int {
var low, high, profit int
bought := false
for i := range prices {
if bought {
high = max(high, prices[i])
if high-prices[i] > fee { // should have sold earlier or not bought
if high-low > fee {
profit += high - low - fee
}
bought = false
} else if prices[i] < low { // regret buying too early
low, high = prices[i], prices[i]
}
}
if !bought && i < len(prices)-1 && prices[i+1] > prices[i] {
bought = true // buy the dip
low, high = prices[i], prices[i]
}
}
if bought && high-low > fee {
profit += high - low - fee
}
return profit
}
var _ = maxProfit

View file

@ -0,0 +1,23 @@
package q735
func asteroidCollision(asteroids []int) []int {
p := 0
for _, a := range asteroids {
if a < 0 {
for p > 0 && asteroids[p-1] > 0 && asteroids[p-1] < -a {
p--
}
if p > 0 && asteroids[p-1] > 0 {
if asteroids[p-1] == -a {
p--
}
continue // explode
}
}
asteroids[p] = a
p++
}
return asteroids[:p]
}
var _ = asteroidCollision

View file

@ -0,0 +1,19 @@
package q739
func dailyTemperatures(temperatures []int) []int {
waitDays := make([]int, len(temperatures))
idxStack := make([]int, 0, len(temperatures))
for i, temp := range temperatures {
for len(idxStack) > 0 && temperatures[idxStack[len(idxStack)-1]] < temp {
popped := idxStack[len(idxStack)-1]
idxStack = idxStack[:len(idxStack)-1] // pop
waitDays[popped] = i - popped
}
idxStack = append(idxStack, i)
}
return waitDays
}
var _ = dailyTemperatures

View file

@ -0,0 +1,24 @@
package q790
const (
TopHalf int8 = iota
BottomHalf
Full
Modulo int = 1e9 + 7
)
func numTilings(n int) int {
cache := make([][3]int, n+1)
cache[0][Full] = 1
cache[1][Full] = 1
for w := 2; w <= n; w++ {
cache[w][Full] = (cache[w-1][Full] + cache[w-2][Full] + cache[w-1][TopHalf] + cache[w-1][BottomHalf]) % Modulo
cache[w][TopHalf] = (cache[w-1][BottomHalf] + cache[w-2][Full]) % Modulo
cache[w][BottomHalf] = (cache[w-1][TopHalf] + cache[w-2][Full]) % Modulo
}
return cache[n][Full]
}
var _ = numTilings

View file

@ -0,0 +1,23 @@
package q841
func canVisitAllRooms(rooms [][]int) bool {
locked := len(rooms) - 1
opened := make([]bool, len(rooms))
opened[0] = true
queue := []int{0}
for ; len(queue) > 0; queue = queue[1:] {
for _, i := range rooms[queue[0]] {
if opened[i] {
continue
}
opened[i] = true
locked--
queue = append(queue, i)
}
}
return locked == 0
}
var _ = canVisitAllRooms

View file

@ -0,0 +1,31 @@
package q875
import (
"math"
"slices"
)
func canEat(piles []int, h, speed int) bool {
needed := 0
for _, n := range piles {
needed += int(math.Ceil(float64(n) / float64(speed)))
}
return needed <= h
}
func minEatingSpeed(piles []int, h int) int {
maxK := slices.Max(piles)
l, r := 1, maxK+1
for l < r {
m := (l + r) / 2
if canEat(piles, h, m) {
r = m
} else {
l = m + 1
}
}
return l
}
var _ = minEatingSpeed

View file

@ -0,0 +1,39 @@
package q901
type Price struct {
day int
price int
}
type StockSpanner struct {
days []Price
currentDay int
}
func Constructor() StockSpanner { return StockSpanner{} }
func (s *StockSpanner) Next(price int) int {
s.currentDay++
curr := Price{day: s.currentDay, price: price}
i := len(s.days) - 1
for ; i >= 0; i-- {
if s.days[i].price > curr.price {
break
}
}
s.days = s.days[:i+1]
ret := s.currentDay
if len(s.days) > 0 {
ret = s.currentDay - s.days[len(s.days)-1].day
}
s.days = append(s.days, curr)
return ret
}
/**
* Your StockSpanner object will be instantiated and called as such:
* obj := Constructor();
* param_1 := obj.Next(price);
*/

View file

@ -0,0 +1,48 @@
package q994
func orangesRotting(grid [][]int) int {
w, h := len(grid[0]), len(grid)
queue := make([][3]int, 0, w+h) // row, col, minute
nFresh, nRot := 0, 0
for r := range grid {
for c := range grid[0] {
switch grid[r][c] {
case 1:
nFresh++
case 2:
nRot++
queue = append(queue, [3]int{r, c, 0})
}
}
}
var rot = func(r, c, minute int) {
if r < 0 || c < 0 || r >= h || c >= w || grid[r][c] != 1 {
return
}
grid[r][c] = 2
nFresh--
nRot++
queue = append(queue, [3]int{r, c, minute})
}
minutes := 0
for ; len(queue) > 0; queue = queue[1:] {
cur := queue[0]
r, c, minute := cur[0], cur[1], cur[2]
minutes = max(minute, minutes)
rot(r, c+1, minute+1)
rot(r, c-1, minute+1)
rot(r+1, c, minute+1)
rot(r-1, c, minute+1)
}
if nFresh == 0 {
return minutes
}
return -1
}
var _ = orangesRotting