add new solutions
This commit is contained in:
parent
9c2c959a9b
commit
9a10695e8c
29 changed files with 1074 additions and 2 deletions
89
solutions/2/q212/solution.go
Normal file
89
solutions/2/q212/solution.go
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
package q212
|
||||
|
||||
type TrieNode struct {
|
||||
children [26]*TrieNode
|
||||
word *string
|
||||
}
|
||||
|
||||
func trieIdx(char byte) int8 {
|
||||
if char < 'a' || char > 'z' {
|
||||
return -1
|
||||
}
|
||||
return int8(char - 'a')
|
||||
}
|
||||
|
||||
func allocator(bulkSize int) func() *TrieNode {
|
||||
var v []TrieNode
|
||||
p := 0
|
||||
|
||||
return func() *TrieNode {
|
||||
if v == nil || p == bulkSize {
|
||||
v = make([]TrieNode, bulkSize)
|
||||
p = 0
|
||||
}
|
||||
p++
|
||||
return &v[p-1]
|
||||
}
|
||||
}
|
||||
|
||||
func buildTrie(words []string) *TrieNode {
|
||||
alloc := allocator(128)
|
||||
root := alloc()
|
||||
for _, word := range words {
|
||||
p := root
|
||||
for i := range len(word) {
|
||||
idx := trieIdx(word[i])
|
||||
if idx < 0 {
|
||||
continue
|
||||
}
|
||||
if p.children[idx] == nil {
|
||||
p.children[idx] = alloc()
|
||||
}
|
||||
p = p.children[idx]
|
||||
}
|
||||
p.word = &word
|
||||
}
|
||||
return root
|
||||
}
|
||||
|
||||
type Coord [2]int8
|
||||
|
||||
func find(board [][]byte, coord Coord, trie *TrieNode, found *[]string) {
|
||||
if coord[0] < 0 || coord[1] < 0 ||
|
||||
int(coord[0]) >= len(board) || int(coord[1]) >= len(board[0]) {
|
||||
return
|
||||
}
|
||||
c := board[coord[0]][coord[1]]
|
||||
idx := trieIdx(c)
|
||||
if idx == -1 || trie.children[idx] == nil {
|
||||
return
|
||||
}
|
||||
// Mark visited
|
||||
board[coord[0]][coord[1]] = '.'
|
||||
|
||||
trie = trie.children[idx]
|
||||
if trie.word != nil {
|
||||
*found = append(*found, *trie.word)
|
||||
trie.word = nil // dedup
|
||||
}
|
||||
|
||||
find(board, Coord{coord[0] + 1, coord[1]}, trie, found)
|
||||
find(board, Coord{coord[0] - 1, coord[1]}, trie, found)
|
||||
find(board, Coord{coord[0], coord[1] + 1}, trie, found)
|
||||
find(board, Coord{coord[0], coord[1] - 1}, trie, found)
|
||||
board[coord[0]][coord[1]] = c
|
||||
}
|
||||
|
||||
func findWords(board [][]byte, words []string) []string {
|
||||
trie := buildTrie(words)
|
||||
found := []string{}
|
||||
|
||||
for row := range board {
|
||||
for col := range board[0] {
|
||||
find(board, Coord{int8(row), int8(col)}, trie, &found)
|
||||
}
|
||||
}
|
||||
return found
|
||||
}
|
||||
|
||||
var _ = findWords
|
||||
Loading…
Add table
Add a link
Reference in a new issue