feat: wednesday
This commit is contained in:
82
pkg/find_median_from_data_stream/main.go
Normal file
82
pkg/find_median_from_data_stream/main.go
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
package findmedianfromdatastream
|
||||||
|
|
||||||
|
import "container/heap"
|
||||||
|
|
||||||
|
type IntHeap []int
|
||||||
|
|
||||||
|
func (h IntHeap) Len() int { return len(h) }
|
||||||
|
func (h IntHeap) Less(i, j int) bool { return h[i] < h[j] }
|
||||||
|
func (h IntHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
|
||||||
|
|
||||||
|
func (h *IntHeap) Push(x any) {
|
||||||
|
*h = append(*h, x.(int))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h IntHeap) Peek() int {
|
||||||
|
return h[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *IntHeap) Pop() any {
|
||||||
|
old := *h
|
||||||
|
x := old[len(old)-1]
|
||||||
|
*h = old[:len(old)-1]
|
||||||
|
return x
|
||||||
|
}
|
||||||
|
|
||||||
|
type MedianFinder struct {
|
||||||
|
// Positive min-heap of top half of values.
|
||||||
|
top *IntHeap
|
||||||
|
// Negative min-heap of bottom half of values.
|
||||||
|
bottom *IntHeap
|
||||||
|
}
|
||||||
|
|
||||||
|
func Constructor() MedianFinder {
|
||||||
|
result := MedianFinder{
|
||||||
|
top: &IntHeap{},
|
||||||
|
bottom: &IntHeap{},
|
||||||
|
}
|
||||||
|
|
||||||
|
heap.Init(result.top)
|
||||||
|
heap.Init(result.bottom)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MedianFinder) AddNum(num int) {
|
||||||
|
if m.bottom.Len() > m.top.Len() {
|
||||||
|
if -m.bottom.Peek() <= num {
|
||||||
|
heap.Push(m.top, num)
|
||||||
|
} else {
|
||||||
|
val := heap.Pop(m.bottom).(int)
|
||||||
|
heap.Push(m.top, -val)
|
||||||
|
heap.Push(m.bottom, -num)
|
||||||
|
}
|
||||||
|
} else if m.bottom.Len() < m.top.Len() {
|
||||||
|
if m.top.Peek() >= num {
|
||||||
|
heap.Push(m.bottom, -num)
|
||||||
|
} else {
|
||||||
|
val := heap.Pop(m.top).(int)
|
||||||
|
heap.Push(m.bottom, -val)
|
||||||
|
heap.Push(m.top, num)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if m.top.Len() == 0 {
|
||||||
|
heap.Push(m.top, num)
|
||||||
|
} else {
|
||||||
|
if median := m.FindMedian(); float64(num) > median {
|
||||||
|
heap.Push(m.top, num)
|
||||||
|
} else {
|
||||||
|
heap.Push(m.bottom, -num)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MedianFinder) FindMedian() float64 {
|
||||||
|
if m.bottom.Len() > m.top.Len() {
|
||||||
|
return float64(-m.bottom.Peek())
|
||||||
|
} else if m.bottom.Len() < m.top.Len() {
|
||||||
|
return float64(m.top.Peek())
|
||||||
|
} else {
|
||||||
|
return float64(m.top.Peek()-m.bottom.Peek()) / 2.0
|
||||||
|
}
|
||||||
|
}
|
||||||
116
pkg/word_search_ii/main.go
Normal file
116
pkg/word_search_ii/main.go
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
package wordsearchii
|
||||||
|
|
||||||
|
type State struct {
|
||||||
|
X, Y int
|
||||||
|
Previous *State
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *State) Visited(x, y int) bool {
|
||||||
|
if s == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if s.X == x && s.Y == y {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.Previous.Visited(x, y)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Trie struct {
|
||||||
|
Children map[byte]*Trie
|
||||||
|
States []*State
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewTrie(board [][]byte) *Trie {
|
||||||
|
trie := &Trie{
|
||||||
|
Children: map[byte]*Trie{},
|
||||||
|
States: []*State{},
|
||||||
|
}
|
||||||
|
|
||||||
|
for x := range board {
|
||||||
|
for y := range board[x] {
|
||||||
|
if _, ok := trie.Children[board[x][y]]; !ok {
|
||||||
|
trie.Children[board[x][y]] = &Trie{
|
||||||
|
Children: map[byte]*Trie{},
|
||||||
|
States: []*State{},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
trie.Children[board[x][y]].States = append(trie.Children[board[x][y]].States, &State{
|
||||||
|
X: x,
|
||||||
|
Y: y,
|
||||||
|
Previous: nil,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return trie
|
||||||
|
}
|
||||||
|
|
||||||
|
var CardinalDirections = [][2]int{
|
||||||
|
{-1, 0},
|
||||||
|
{1, 0},
|
||||||
|
{0, -1},
|
||||||
|
{0, 1},
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Trie) Explore(board [][]byte, ch byte) *Trie {
|
||||||
|
child := &Trie{
|
||||||
|
Children: map[byte]*Trie{},
|
||||||
|
States: []*State{},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, state := range t.States {
|
||||||
|
for _, direction := range CardinalDirections {
|
||||||
|
xNew, yNew := state.X+direction[0], state.Y+direction[1]
|
||||||
|
|
||||||
|
if xNew < 0 || xNew >= len(board) || yNew < 0 || yNew >= len(board[xNew]) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if state.Visited(xNew, yNew) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if ch != board[xNew][yNew] {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
child.States = append(child.States, &State{
|
||||||
|
X: xNew,
|
||||||
|
Y: yNew,
|
||||||
|
Previous: state,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Children[ch] = child
|
||||||
|
return child
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Trie) FindWord(board [][]byte, word string) bool {
|
||||||
|
if len(word) == 0 {
|
||||||
|
return len(t.States) > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
child, ok := t.Children[word[0]]
|
||||||
|
if !ok {
|
||||||
|
child = t.Explore(board, word[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
return child.FindWord(board, word[1:])
|
||||||
|
}
|
||||||
|
|
||||||
|
func FindWords(board [][]byte, words []string) []string {
|
||||||
|
trie := NewTrie(board)
|
||||||
|
found := []string{}
|
||||||
|
|
||||||
|
for _, word := range words {
|
||||||
|
if trie.FindWord(board, word) {
|
||||||
|
found = append(found, word)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return found
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user