Published on

Word Boggle

Authors

Problem

Similar with word search problem but the goals is find all words in the board and return with sorted words.


_5
board = [
_5
['R', 'L', 'D'],
_5
['U', 'O', 'E'],
_5
['C', 'S', 'O']
_5
]

and words = ["CODE", "SOLO", "RULES", "COOL"], the output should be solution(board, words) = ["CODE", "RULES"].

Backtracking without trie


_45
import "sort"
_45
func solution(board [][]string, words []string) []string {
_45
result := []string{}
_45
for _, word := range words {
_45
if canBoggle(board, word, [][2]int{}) {
_45
result = append(result, word)
_45
}
_45
}
_45
sort.Strings(result)
_45
return result
_45
}
_45
_45
func canBoggle(board [][]string, word string, used [][2]int) bool {
_45
if len(word) == 0 {
_45
return true
_45
}
_45
for i := 0; i < len(board); i++ {
_45
for j := 0; j < len(board[0]); j++ {
_45
if !isUsed(used, i, j) && board[i][j] == string(word[0]) {
_45
if len(used) == 0 || (abs(used[len(used)-1][0]-i) <= 1 && abs(used[len(used)-1][1]-j) <= 1) {
_45
if canBoggle(board, word[1:], append(used, [2]int{i, j})) {
_45
return true
_45
}
_45
}
_45
}
_45
}
_45
}
_45
return false
_45
}
_45
_45
func abs(n int) int {
_45
if n < 0 {
_45
return -n
_45
}
_45
return n
_45
}
_45
_45
func isUsed(used [][2]int, i int, j int) bool {
_45
for _, coordinate := range used {
_45
if coordinate[0] == i && coordinate[1] == j {
_45
return true
_45
}
_45
}
_45
return false
_45
}

Backtracking with trie


_66
import "sort"
_66
type Trie struct {
_66
children map[byte]*Trie
_66
word string
_66
}
_66
_66
func (t *Trie) Insert(word string) {
_66
node := t
_66
for i := range word {
_66
ch := word[i]
_66
if node.children[ch] == nil {
_66
node.children[ch] = &Trie{children: map[byte]*Trie{}}
_66
}
_66
node = node.children[ch]
_66
}
_66
node.word = word
_66
}
_66
_66
var dirs = []struct{ x, y int }{{-1, 0}, {1, 0}, {0, -1}, {0, 1}, {1, 1}, {-1, 1}, {-1,-1},{1,-1}}
_66
_66
func solution(board [][]string, words []string) (ans []string) {
_66
ans=[]string{}
_66
t := &Trie{children: map[byte]*Trie{}}
_66
for _, word := range words {
_66
t.Insert(word)
_66
}
_66
_66
m, n := len(board), len(board[0])
_66
_66
var dfs func(node *Trie, x, y int)
_66
dfs = func(node *Trie, x, y int) {
_66
ch := board[x][y]
_66
nxt := node.children[ch[0]]
_66
if nxt == nil {
_66
return
_66
}
_66
_66
if nxt.word != "" {
_66
ans = append(ans, nxt.word)
_66
nxt.word = ""
_66
}
_66
_66
if len(nxt.children) > 0 {
_66
board[x][y] = "#"
_66
for _, d := range dirs {
_66
nx, ny := x+d.x, y+d.y
_66
if 0 <= nx && nx < m && 0 <= ny && ny < n && board[nx][ny] != "#" {
_66
dfs(nxt, nx, ny)
_66
}
_66
}
_66
board[x][y] = ch
_66
}
_66
_66
if len(nxt.children) == 0 {
_66
delete(node.children, ch[0])
_66
}
_66
}
_66
for i, row := range board {
_66
for j := range row {
_66
dfs(t, i, j)
_66
}
_66
}
_66
sort.Strings(ans)
_66
_66
return
_66
}