add new solutions
This commit is contained in:
parent
9c2c959a9b
commit
9a10695e8c
29 changed files with 1074 additions and 2 deletions
35
solutions/1/q105/solution.go
Normal file
35
solutions/1/q105/solution.go
Normal 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
|
||||
35
solutions/1/q114/solution.go
Normal file
35
solutions/1/q114/solution.go
Normal 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
|
||||
63
solutions/1/q127/solution.go
Normal file
63
solutions/1/q127/solution.go
Normal 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
|
||||
39
solutions/1/q133/solution.go
Normal file
39
solutions/1/q133/solution.go
Normal 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
|
||||
22
solutions/1/q137/solution.go
Normal file
22
solutions/1/q137/solution.go
Normal 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
|
||||
112
solutions/1/q146/solution.go
Normal file
112
solutions/1/q146/solution.go
Normal 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);
|
||||
*/
|
||||
19
solutions/1/q151/solution.go
Normal file
19
solutions/1/q151/solution.go
Normal 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
|
||||
44
solutions/1/q155/solution.go
Normal file
44
solutions/1/q155/solution.go
Normal 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();
|
||||
*/
|
||||
21
solutions/1/q172/solution.go
Normal file
21
solutions/1/q172/solution.go
Normal 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
|
||||
13
solutions/1/q198/solution.go
Normal file
13
solutions/1/q198/solution.go
Normal 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
|
||||
Loading…
Add table
Add a link
Reference in a new issue