212.word-search-ii.go 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. func findWords(board [][]byte, words []string) (ans []string) {
  2. trie := &TrieNode{}
  3. for i := range words {
  4. trie.Insert(words[i])
  5. }
  6. for y := range board {
  7. for x := range board[y] {
  8. DFS(board, trie, trie, x, y, &ans, []byte{})
  9. }
  10. }
  11. return
  12. }
  13. func DFS(board [][]byte, trie, curr *TrieNode, x, y int, ans *[]string, prev []byte) {
  14. ch := board[y][x]
  15. if ch == '*' { // Visited
  16. return
  17. }
  18. curr = curr.OneStepSearch(ch)
  19. if curr == nil {
  20. return
  21. }
  22. path := make([]byte, len(prev))
  23. copy(path, prev)
  24. path = append(path, ch)
  25. if curr.IsKey {
  26. *ans = append(*ans, string(path))
  27. trie.Delete(path)
  28. }
  29. board[y][x] = '*' // Mark (x, y) as visited
  30. if 0 < x {
  31. DFS(board, trie, curr, x-1, y, ans, path)
  32. }
  33. if 0 < y {
  34. DFS(board, trie, curr, x, y-1, ans, path)
  35. }
  36. if x < len(board[0])-1 {
  37. DFS(board, trie, curr, x+1, y, ans, path)
  38. }
  39. if y < len(board)-1 {
  40. DFS(board, trie, curr, x, y+1, ans, path)
  41. }
  42. board[y][x] = ch
  43. }
  44. type TrieNode struct {
  45. Cnt int
  46. IsKey bool
  47. Children *[26]TrieNode
  48. }
  49. func (root *TrieNode) Insert(word string) {
  50. for i := range word {
  51. if root.Children == nil {
  52. root.Children = &[26]TrieNode{}
  53. }
  54. root = &root.Children[int(word[i]-'a')]
  55. root.Cnt++
  56. }
  57. root.IsKey = true
  58. }
  59. func (root *TrieNode) Delete(word []byte) {
  60. for i := range word {
  61. root = &root.Children[int(word[i]-'a')]
  62. root.Cnt--
  63. }
  64. root.IsKey = false
  65. }
  66. func (root *TrieNode) OneStepSearch(ch byte) *TrieNode {
  67. if root.Children == nil {
  68. return nil
  69. }
  70. root = &root.Children[int(ch-'a')]
  71. if root.Cnt == 0 {
  72. return nil
  73. }
  74. return root
  75. }