Word Search in Grid Using Backtracking in DSA Typescript - Time & Space Complexity
We want to understand how the time needed to find a word in a grid grows as the grid and word sizes increase.
Specifically, how does the search time change when we try all possible paths to match the word?
Analyze the time complexity of the following code snippet.
function exist(board: string[][], word: string): boolean {
const rows = board.length;
const cols = board[0].length;
function backtrack(r: number, c: number, index: number): boolean {
if (index === word.length) return true;
if (r < 0 || c < 0 || r >= rows || c >= cols || board[r][c] !== word[index]) return false;
const temp = board[r][c];
board[r][c] = '#';
const found = backtrack(r+1, c, index+1) || backtrack(r-1, c, index+1) || backtrack(r, c+1, index+1) || backtrack(r, c-1, index+1);
board[r][c] = temp;
return found;
}
for (let i = 0; i < rows; i++) {
for (let j = 0; j < cols; j++) {
if (backtrack(i, j, 0)) return true;
}
}
return false;
}
This code tries to find the given word in the grid by exploring all possible paths using backtracking.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: The recursive backtracking function explores up to 4 directions for each letter in the word.
- How many times: For each cell in the grid (rows * cols), it may explore up to 4 choices for each character in the word (word length).
As the grid size and word length grow, the number of paths to check grows very fast.
| Input Size (n = rows * cols) | Word Length (m) | Approx. Operations |
|---|---|---|
| 10 | 3 | About 10 * 4^3 = 640 |
| 100 | 5 | About 100 * 4^5 = 10,2400 |
| 1000 | 6 | About 1000 * 4^6 = 4,096,000 |
Pattern observation: The operations grow exponentially with the word length and linearly with the grid size.
Time Complexity: O(N * 4^M)
This means the time grows linearly with the number of cells in the grid and exponentially with the length of the word.
[X] Wrong: "The search only takes time proportional to the grid size because we just check each cell once."
[OK] Correct: Because the search explores many paths recursively for each letter, it can revisit cells in different paths, causing exponential growth with word length.
Understanding this complexity helps you explain how backtracking explores many possibilities and why pruning or constraints matter in real problems.
"What if we limited the search to only horizontal and vertical directions instead of all four directions? How would the time complexity change?"
Practice
Solution
Step 1: Understand backtracking role
Backtracking tries all possible paths from each cell to find the target word.Step 2: Eliminate other options
Sorting, counting, or replacing characters are unrelated to backtracking in word search.Final Answer:
To explore all possible paths to find the word -> Option BQuick Check:
Backtracking = Explore paths [OK]
- Thinking backtracking sorts or counts
- Confusing backtracking with simple search
- Ignoring path exploration in grid
Solution
Step 1: Identify correct parameters
The helper needs the grid, the word, current position (row, col), and index in word to track progress.Step 2: Check return type
It returns boolean to indicate if word is found along the path.Final Answer:
function backtrack(grid: string[][], word: string, row: number, col: number, index: number): boolean -> Option AQuick Check:
Correct params and boolean return = function backtrack(grid: string[][], word: string, row: number, col: number, index: number): boolean [OK]
- Missing row and col parameters
- Wrong return type (void or number)
- Incorrect parameter order
const board = [
['A','B','C','E'],
['S','F','C','S'],
['A','D','E','E']
];
function exist(board: string[][], word: string): boolean {
const rows = board.length;
const cols = board[0].length;
function backtrack(r: number, c: number, i: number): boolean {
if (i === word.length) return true;
if (r < 0 || c < 0 || r >= rows || c >= cols || board[r][c] !== word[i]) return false;
const temp = board[r][c];
board[r][c] = '#';
const 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 (let r = 0; r < rows; r++) {
for (let c = 0; c < cols; c++) {
if (backtrack(r, c, 0)) return true;
}
}
return false;
}
console.log(exist(board, 'ABCCED'));Solution
Step 1: Understand the board and word
The word 'ABCCED' can be found by moving right and down in the grid starting at (0,0).Step 2: Trace backtracking calls
Backtracking marks visited cells and explores neighbors; it finds the word successfully and returns true.Final Answer:
true -> Option CQuick Check:
Word found in grid = true [OK]
- Assuming word is not found
- Ignoring visited cell marking
- Confusing return values
function backtrack(r: number, c: number, i: number): boolean {
if (i === word.length) return true;
if (r < 0 || c < 0 || r >= rows || c >= cols) return false;
if (board[r][c] !== word[i]) return false;
board[r][c] = '#';
const 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);
return found;
}Solution
Step 1: Identify missing restoration
The function marks board[r][c] as '#' but never restores it after recursion, corrupting the grid.Step 2: Fix by restoring cell
After recursive calls, restore board[r][c] to original character to allow other paths to use it.Final Answer:
Restore board[r][c] to original after recursive calls -> Option AQuick Check:
Restore cell after recursion = Restore board[r][c] to original after recursive calls [OK]
- Forgetting to restore visited cells
- Changing base case incorrectly
- Removing necessary boundary checks
Solution
Step 1: Understand inefficiency of separate searches
Running backtracking for each word separately repeats work and is slow for many words.Step 2: Use Trie with backtracking
Building a Trie of all words allows one backtracking pass to find all words efficiently by pruning invalid paths early.Final Answer:
Use a Trie to store words and backtrack once to find all matches -> Option DQuick Check:
Trie + single backtracking = efficient search [OK]
- Searching each word separately wastes time
- Sorting words doesn't help search
- Modifying grid destructively before search
Ready to prove it?
Pass the test and this pattern moves unknown
