add new solutions

This commit is contained in:
kanna5 2026-01-05 16:48:03 +09:00
parent 9c2c959a9b
commit 9a10695e8c
Signed by: kkyy
GPG key ID: 06332F3965E9B0CF
29 changed files with 1074 additions and 2 deletions

View file

@ -0,0 +1,35 @@
package q105
type TreeNode struct {
Val int
Left *TreeNode
Right *TreeNode
}
func bld(preorder []int, inorder map[int]int, pL, pR, iL, iR int) *TreeNode {
if pL == pR {
return nil
}
val := preorder[pL]
p := inorder[val] // position of val in "inorder"
left := bld(preorder, inorder, pL+1, pL+1+p-iL, iL, p)
right := bld(preorder, inorder, pL+1+p-iL, pR, p+1, iR)
return &TreeNode{
Val: val,
Left: left,
Right: right,
}
}
func buildTree(preorder []int, inorder []int) *TreeNode {
iIdx := make(map[int]int, len(inorder))
for i := range inorder {
iIdx[inorder[i]] = i
}
return bld(preorder, iIdx, 0, len(preorder), 0, len(preorder))
}
var _ = buildTree

View file

@ -0,0 +1,35 @@
package q114
type TreeNode struct {
Val int
Left *TreeNode
Right *TreeNode
}
func fl(node *TreeNode) (head, tail *TreeNode) {
if node == nil {
return nil, nil
}
head, tail = node, node
lhead, ltail := fl(node.Left)
rhead, rtail := fl(node.Right)
if lhead != nil {
node.Left = nil
node.Right = lhead
tail = ltail
}
if rhead != nil {
tail.Right = rhead
tail = rtail
}
return
}
func flatten(root *TreeNode) {
fl(root)
}
var _ = flatten

View file

@ -0,0 +1,63 @@
package q127
// Ideas for improvement: use a hashmap to index strings instead of an O(n^2)
// comparison and neighbor matrix; use bidirectional BFS.
func reachable(a, b string) bool {
diff := false
for i := range len(a) {
if a[i] != b[i] {
if diff {
return false
}
diff = true
}
}
return diff // exactly one different char
}
func ladderLength(beginWord string, endWord string, wordList []string) int {
target := -1
neighbors := make([][]int, len(wordList))
for i := range wordList {
if target == -1 && wordList[i] == endWord {
target = i
}
for j := i + 1; j < len(wordList); j++ {
if reachable(wordList[i], wordList[j]) {
neighbors[i] = append(neighbors[i], j)
neighbors[j] = append(neighbors[j], i)
}
}
}
if target == -1 {
return 0
}
seen := make([]bool, len(wordList))
queue := make([][2]int, 0, len(wordList)) // index, steps
for i := range wordList {
if reachable(beginWord, wordList[i]) {
seen[i] = true
queue = append(queue, [2]int{i, 2})
}
}
for ; len(queue) > 0; queue = queue[1:] {
id, step := queue[0][0], queue[0][1]
if id == target {
return step
}
for _, n := range neighbors[id] {
if !seen[n] {
seen[n] = true
queue = append(queue, [2]int{n, step + 1})
}
}
}
return 0
}
var _ = ladderLength

View file

@ -0,0 +1,39 @@
package q133
type Node struct {
Val int
Neighbors []*Node
}
func cloneGraph(node *Node) *Node {
if node == nil {
return nil
}
seen := map[*Node]*Node{}
queue := []*Node{node}
for ; len(queue) > 0; queue = queue[1:] {
cur := queue[0]
if _, ok := seen[cur]; ok {
continue
}
cloned := &Node{
Val: cur.Val,
Neighbors: []*Node{},
}
seen[cur] = cloned
for _, n := range cur.Neighbors {
if nCloned, ok := seen[n]; ok {
// Link
cloned.Neighbors = append(cloned.Neighbors, nCloned)
nCloned.Neighbors = append(nCloned.Neighbors, cloned)
} else {
// Add to queue
queue = append(queue, n)
}
}
}
return seen[node]
}
var _ = cloneGraph

View file

@ -0,0 +1,22 @@
package q137
func singleNumber(nums []int) int {
bitCounts := make([]uint8, 32)
for _, num := range nums {
num32 := int32(num)
for i := range 32 {
if num32|1<<i == num32 {
bitCounts[i] = (bitCounts[i] + 1) % 3
}
}
}
var ret int32
for i := range 32 {
if bitCounts[i] != 0 {
ret |= 1 << i
}
}
return int(ret)
}
var _ = singleNumber

View file

@ -0,0 +1,112 @@
package q146
type lruNode struct {
key, val int
prev, next *lruNode
}
type LRUCache struct {
cap int
index map[int]*lruNode
head, tail *lruNode
nodes []lruNode
p int
}
func Constructor(capacity int) LRUCache {
return LRUCache{
cap: capacity,
index: make(map[int]*lruNode, capacity),
nodes: make([]lruNode, capacity),
}
}
func (c *LRUCache) alloc() *lruNode {
if c.p < len(c.nodes) {
c.p++
return &c.nodes[c.p-1]
}
return nil
}
func (c *LRUCache) touch(node *lruNode) {
if node.prev == nil {
return
}
if c.tail == node {
c.tail = node.prev
} else {
node.next.prev = node.prev
}
node.prev.next = node.next
node.prev = nil
node.next = c.head
c.head.prev = node
c.head = node
}
func (c *LRUCache) evict() *lruNode {
if len(c.index) < c.cap {
return nil
}
node := c.tail
delete(c.index, node.key)
if node.prev == nil {
c.head, c.tail = nil, nil
} else {
c.tail = node.prev
c.tail.next = nil
}
return node
}
func (c *LRUCache) Get(key int) int {
node := c.index[key]
if node == nil {
return -1
}
c.touch(node)
return node.val
}
func (c *LRUCache) Put(key int, value int) {
if c.cap == 0 {
return
}
node := c.index[key]
if node != nil {
node.val = value
c.touch(node)
return
}
node = c.alloc()
if node == nil {
node = c.evict()
*node = lruNode{} // clear
}
node.key, node.val = key, value
c.index[key] = node
node.next = c.head
if c.head != nil {
c.head.prev = node
}
c.head = node
if c.tail == nil {
c.tail = node
}
}
/**
* Your LRUCache object will be instantiated and called as such:
* obj := Constructor(capacity);
* param_1 := obj.Get(key);
* obj.Put(key,value);
*/

View file

@ -0,0 +1,19 @@
package q151
import "strings"
func reverseWords(s string) string {
b := strings.Builder{}
fields := strings.Fields(s)
if len(fields) > 0 {
b.WriteString(fields[len(fields)-1])
}
for i := len(fields) - 2; i >= 0; i-- {
b.WriteByte(' ')
b.WriteString(fields[i])
}
return b.String()
}
var _ = reverseWords

View file

@ -0,0 +1,44 @@
package q155
type stackElem struct {
val, min int
}
type MinStack struct {
stack []stackElem
}
func Constructor() MinStack {
return MinStack{}
}
func (s *MinStack) Push(val int) {
minVal := val
if len(s.stack) > 0 {
minVal = min(minVal, s.GetMin())
}
s.stack = append(s.stack, stackElem{
val: val, min: minVal,
})
}
func (s *MinStack) Pop() {
s.stack = s.stack[:len(s.stack)-1]
}
func (s *MinStack) Top() int {
return s.stack[len(s.stack)-1].val
}
func (s *MinStack) GetMin() int {
return s.stack[len(s.stack)-1].min
}
/**
* Your MinStack object will be instantiated and called as such:
* obj := Constructor();
* obj.Push(val);
* obj.Pop();
* param_3 := obj.Top();
* param_4 := obj.GetMin();
*/

View file

@ -0,0 +1,21 @@
package q172
// Note: actually, counting 5 alone is enough since 2 certainly occurs more than 5.
func trailingZeroes(n int) int {
count2, count5 := 0, 0
for i := 2; i <= n; i++ {
num := i
for num%2 == 0 {
num /= 2
count2++
}
for num%5 == 0 {
num /= 5
count5++
}
}
return min(count2, count5)
}
var _ = trailingZeroes

View file

@ -0,0 +1,13 @@
package q198
func rob(nums []int) int {
if len(nums) > 1 {
nums[1] = max(nums[0], nums[1])
}
for i := 2; i < len(nums); i++ {
nums[i] = max(nums[i-2]+nums[i], nums[i-1])
}
return nums[len(nums)-1]
}
var _ = rob