Word Search: Traversing a Letter Grid to Form Words
The "Word Search" problem involves searching for a specific word in a grid of letters, where the word can be formed by connecting letters horizontally or vertically.
Problem Statement
Given a 2D board of letters and a word, check if the word exists in the grid. The word can be constructed from letters of sequentially adjacent cells, where "adjacent" cells are those horizontally or vertically neighboring.
Example

- Input: Board:
[
["A", "B", "C", "E"],
["S", "F", "C", "S"],
["A", "D", "E", "E"]
]
Word: "ABCCED"
- Output:
true
Solution Approach (typescript)
function exist(board: string[][], word: string): boolean {
function dfs(board: string[][], i: number, j: number, count: number, word: string): boolean {
if (count === word.length) return true;
if (
i < 0 ||
i >= board.length ||
j < 0 ||
j >= board[i].length ||
board[i][j] !== word[count]
) {
return false;
}
let temp = board[i][j];
board[i][j] = " ";
let found =
dfs(board, i + 1, j, count + 1, word) ||
dfs(board, i - 1, j, count + 1, word) ||
dfs(board, i, j + 1, count + 1, word) ||
dfs(board, i, j - 1, count + 1, word);
board[i][j] = temp;
return found;
}
for (let i = 0; i < board.length; i++) {
for (let j = 0; j < board[i].length; j++) {
if (board[i][j] === word[0] && dfs(board, i, j, 0, word)) {
return true;
}
}
}
return false;
}
Breaking Down the Solution
- Depth-First Search (DFS): Use DFS to traverse the board, exploring each possible path.
- Check Each Cell: Start from each cell that matches the first letter of the word, and recursively check its neighbors.
- Track Progress: Temporarily mark cells as visited during each DFS iteration to avoid revisiting them in the same path.
- Return Result: If the word is found, return
true; if the board is fully explored without finding the word, returnfalse.
Solution in Go
package main
import (
"fmt"
)
func exist(board [][]byte, word string) bool {
for i := 0; i < len(board); i++ {
for j := 0; j < len(board[i]); j++ {
if dfs(board, i, j, word, 0) {
return true
}
}
}
return false
}
func dfs(board [][]byte, i, j int, word string, count int) bool {
if count == len(word) {
return true
}
if i < 0 || i >= len(board) || j < 0 || j >= len(board[0]) || board[i][j] != word[count] {
return false
}
temp := board[i][j]
board[i][j] = byte(' ')
found := dfs(board, i+1, j, word, count+1) ||
dfs(board, i-1, j, word, count+1) ||
dfs(board, i, j+1, word, count+1) ||
dfs(board, i, j-1, word, count+1)
board[i][j] = temp
return found
}
func main() {
board := [][]byte{
{'A', 'B', 'C', 'E'},
{'S', 'F', 'C', 'S'},
{'A', 'D', 'E', 'E'},
}
word := "ABCCED"
fmt.Println(exist(board, word)) // Output: true
}
In this Go implementation:
- The
existfunction checks if a given word exists in the board. It iterates over each cell in the board and calls thedfs(Depth-First Search) function. - The
dfsfunction performs a depth-first search from the current cell to check if the remaining characters of the word can be formed. It marks the cell as visited by replacing the character with a space and then recursively checks adjacent cells. - If
dfsreturnstrueat any point,existwill returntrue, indicating the word is found in the board. - After the recursive call, the cell's original character is restored.
Solution in C++
#include <iostream>
#include <vector>
using namespace std;
bool dfs(vector<vector<char>>& board, int i, int j, string& word, int count) {
if (count == word.length()) {
return true;
}
if (i < 0 || i >= board.size() || j < 0 || j >= board[0].size() || board[i][j] != word[count]) {
return false;
}
char temp = board[i][j];
board[i][j] = ' ';
bool found = dfs(board, i + 1, j, word, count + 1)
|| dfs(board, i - 1, j, word, count + 1)
|| dfs(board, i, j + 1, word, count + 1)
|| dfs(board, i, j - 1, word, count + 1);
board[i][j] = temp;
return found;
}
bool exist(vector<vector<char>>& board, string word) {
for (int i = 0; i < board.size(); i++) {
for (int j = 0; j < board[i].size(); j++) {
if (board[i][j] == word[0] && dfs(board, i, j, word, 0)) {
return true;
}
}
}
return false;
}
int main() {
vector<vector<char>> board = {
{'A','B','C','E'},
{'S','F','C','S'},
{'A','D','E','E'}
};
string word = "ABCCED";
cout << (exist(board, word) ? "true" : "false") << endl;
return 0;
}
In this C++ solution:
- The
dfsfunction performs a depth-first search from the current cell, recursively checking adjacent cells to form the word. It temporarily marks the cell as visited by setting it to a space character and restores it after the recursive calls. - The
existfunction iterates over each cell in the board, starting a new DFS search whenever it finds the first character of the word. - If
dfsreturnstruefor any starting cell, the entire function returnstrue, indicating the word is found. - Compile and run this program to check if the given word exists in the board.
Solution in Python
def exist(board, word):
def dfs(board, i, j, word, count):
if count == len(word):
return True
if i < 0 or i >= len(board) or j < 0 or j >= len(board[0]) or board[i][j] != word[count]:
return False
temp = board[i][j]
board[i][j] = ' ' # Mark as visited
found = dfs(board, i + 1, j, word, count + 1) or \
dfs(board, i - 1, j, word, count + 1) or \
dfs(board, i, j + 1, word, count + 1) or \
dfs(board, i, j - 1, word, count + 1)
board[i][j] = temp # Reset the state
return found
for i in range(len(board)):
for j in range(len(board[0])):
if board[i][j] == word[0] and dfs(board, i, j, word, 0):
return True
return False
# Example usage
board = [
['A', 'B', 'C', 'E'],
['S', 'F', 'C', 'S'],
['A', 'D', 'E', 'E']
]
word = "ABCCED"
print(exist(board, word)) # Output: True
In this Python solution:
- The
dfsfunction is defined withinexistto utilize the scope ofboardandword. It performs a depth-first search from the current cell. - The cell is temporarily marked as visited by setting it to a space character, and then restored to its original value after the recursive calls.
existiterates over the board, callingdfsfor each cell that matches the first letter of the word.- If
dfsreturnsTrue, the word exists in the board; otherwise, it does not.
Solution in Java
public class WordSearch {
public boolean exist(char[][] board, String word) {
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[i].length; j++) {
if (board[i][j] == word.charAt(0) && dfs(board, i, j, 0, word)) {
return true;
}
}
}
return false;
}
private boolean dfs(char[][] board, int i, int j, int count, String word) {
if (count == word.length()) return true;
if (i < 0 || i >= board.length || j < 0 || j >= board[0].length || board[i][j] != word.charAt(count)) return false;
char temp = board[i][j];
board[i][j] = ' '; // Mark as visited
boolean found = dfs(board, i + 1, j, count + 1, word)
|| dfs(board, i - 1, j, count + 1, word)
|| dfs(board, i, j + 1, count + 1, word)
|| dfs(board, i, j - 1, count + 1, word);
board[i][j] = temp; // Reset state
return found;
}
public static void main(String[] args) {
WordSearch solution = new WordSearch();
char[][] board = {
{'A', 'B', 'C', 'E'},
{'S', 'F', 'C', 'S'},
{'A', 'D', 'E', 'E'}
};
String word = "ABCCED";
System.out.println(solution.exist(board, word)); // Output: true
}
}
In this Java solution:
- The
existmethod iterates over each cell in the board, starting a DFS search from cells that match the first character of the word. - The
dfsmethod performs a depth-first search to check if the word can be formed, starting from the current cell. It marks the cell as visited by setting it to a space character and resets it to its original value after exploring all possible paths from that cell. - If
dfsreturnstrueat any point,existwill returntrue, indicating that the word is found in the board. - The
mainmethod demonstrates how to use theWordSearchclass with a sample board and word.
Solution in Kotlin
class WordSearch {
fun exist(board: Array<CharArray>, word: String): Boolean {
for (i in board.indices) {
for (j in board[0].indices) {
if (board[i][j] == word[0] && dfs(board, i, j, 0, word)) {
return true
}
}
}
return false
}
private fun dfs(board: Array<CharArray>, i: Int, j: Int, count: Int, word: String): Boolean {
if (count == word.length) return true
if (i < 0 || i >= board.size || j < 0 || j >= board[0].size || board[i][j] != word[count]) return false
val temp = board[i][j]
board[i][j] = ' ' // Mark as visited
val found = dfs(board, i + 1, j, count + 1, word)
|| dfs(board, i - 1, j, count + 1, word)
|| dfs(board, i, j + 1, count + 1, word)
|| dfs(board, i, j - 1, count + 1, word)
board[i][j] = temp // Reset state
return found
}
}
fun main() {
val solution = WordSearch()
val board = arrayOf(
charArrayOf('A', 'B', 'C', 'E'),
charArrayOf('S', 'F', 'C', 'S'),
charArrayOf('A', 'D', 'E', 'E')
)
val word = "ABCCED"
println(solution.exist(board, word)) // Output: true
}
In this Kotlin solution:
- The
existfunction iterates over each cell in the board, starting a DFS search from cells that match the first character of the word. - The
dfsfunction performs a depth-first search to check if the word can be formed, starting from the current cell. It marks the cell as visited by setting it to a space character and resets it to its original value after the recursive calls. - If
dfsreturnstruefor any starting cell,existwill returntrue, indicating the word is found in the board. - The
mainfunction demonstrates how to use theWordSearchclass with a sample board and word.
Conclusion
The Word Search problem is a classic example of using DFS in a matrix-like structure. It tests one's ability to implement recursive search algorithms and handle edge cases in grid traversal.
Comments (0)
Stub — comments live in your browser only (localStorage). No server round-trip yet.
No comments yet. Be the first.