package main import "fmt" func exist(board [][]byte, word string) bool { rows := len(board) cols := len(board[0]) var backtrack func(r, c, i int) bool backtrack = func(r, c, i int) bool { if i == len(word) { return true } if r < 0 || c < 0 || r >= rows || c >= cols || board[r][c] != word[i] { return false } temp := board[r][c] board[r][c] = '#' found := backtrack(r+1, c, i+1) || backtrack(r-1, c, i+1) || backtrack(r, c+1, i+1) || backtrack(r, c-1, i+1) board[r][c] = temp return found } for i := 0; i < rows; i++ { for j := 0; j < cols; j++ { if backtrack(i, j, 0) { return true } } } return false } func main() { board := [][]byte{ {'C', 'A', 'T'}, {'X', 'Y', 'Z'}, {'A', 'B', 'C'}, } fmt.Println(exist(board, "CAT")) }
The word "CAT" can be found starting at board[0][0] moving right to board[0][1] and then board[0][2]. The backtracking function returns true.
package main import "fmt" func exist(board [][]byte, word string) bool { rows := len(board) cols := len(board[0]) var backtrack func(r, c, i int) bool backtrack = func(r, c, i int) bool { if i == len(word) { return true } if r < 0 || c < 0 || r >= rows || c >= cols || board[r][c] != word[i] { return false } temp := board[r][c] board[r][c] = '#' found := backtrack(r+1, c, i+1) || backtrack(r-1, c, i+1) || backtrack(r, c+1, i+1) || backtrack(r, c-1, i+1) board[r][c] = temp return found } for i := 0; i < rows; i++ { for j := 0; j < cols; j++ { if backtrack(i, j, 0) { return true } } } return false } func main() { board := [][]byte{ {'C', 'A', 'T'}, {'X', 'Y', 'Z'}, {'A', 'B', 'C'}, } fmt.Println(exist(board, "DOG")) }
The word "DOG" cannot be found anywhere in the grid, so the function returns false.
Marking a cell as visited prevents the algorithm from using the same cell multiple times in the current path, which avoids infinite loops and incorrect matches.
package main import "fmt" func exist(board [][]byte, word string) bool { rows := len(board) cols := len(board[0]) var backtrack func(r, c, i int) bool backtrack = func(r, c, i int) bool { if i == len(word) { return true } if r < 0 || c < 0 || r >= rows || c >= cols || board[r][c] != word[i] { return false } temp := board[r][c] board[r][c] = '#' found := backtrack(r+1, c, i+1) || backtrack(r-1, c, i+1) || backtrack(r, c+1, i+1) || backtrack(r, c-1, i+1) // Missing restoration of board[r][c] return found } for i := 0; i < rows; i++ { for j := 0; j < cols; j++ { if backtrack(i, j, 0) { return true } } } return false } func main() { board := [][]byte{ {'C', 'A', 'T'}, {'X', 'Y', 'Z'}, {'A', 'B', 'C'}, } fmt.Println(exist(board, "CAT")) }
The code does not restore the original letter after marking it as '#', so subsequent searches see corrupted board cells and fail to find the word.
Marking visited cells temporarily ensures paths do not reuse the same cell. Restoring cells allows counting all distinct occurrences. BFS or permanent removal do not correctly count all occurrences.
