feat: osijvrsoi
This commit is contained in:
116
pkg/questions/word_search_ii/main.go
Normal file
116
pkg/questions/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