Word Search
Problem
Given a 2-D grid of characters board and a string word, return true if the word is present in the grid, otherwise return false.
For the word to be present it must be possible to form it with a path in the board with horizontally or vertically neighboring cells. The same cell may not be used more than once in a word.
Examples
Example 1:

Input:
board = [
["A","B","C","D"],
["S","A","A","T"],
["A","C","A","E"]
],
word = "CAT"
Example 2:

Input:
board = [
["A","B","C","D"],
["S","A","A","T"],
["A","C","A","E"]
],
word = "BAT"
Output: false
Constraints
1 <= board.length, board[i].length <= 51 <= word.length <= 10boardandwordconsists of only lowercase and uppercase English letters.
You should aim for a solution with O(m * (4^n)) time and O(n) space, where m is the number of cells in the given board and n is the size of the given word.
Solution
Loop over each starting cell. For each cell, perform a DFS, while tracking the path cells.
class Solution {
public:
bool exist(vector<vector<char>>& board, const string &word) {
const auto ROWS = board.size();
const auto COLS = board[0].size();
std::unordered_set<int> path_indices;
std::function<bool(int, int, int)> runner;
runner = [&](int r, int c, int w_idx) -> bool {
// If (r,c) invalid index
if (r < 0 || c < 0 || r >= ROWS || c >= COLS) {
return false;
}
// If our path is too long, quit
if (w_idx >= word.size()) {
return false;
}
// If this is a index already in the path, quit
auto flat_idx = r * COLS + c;
if (path_indices.contains(flat_idx)) {
return false;
}
// If (r,c) does not contain word[w_idx], quit
// Otherwise, check if we found the last char in the word
if (board[r][c] != word[w_idx]) {
return false;
} else if (w_idx == word.size() - 1) {
return true;
}
// We have a partial match
// Check the next word character in all directions
path_indices.insert(flat_idx);
if (runner(r - 1, c, w_idx + 1)) { return true; }
if (runner(r + 1, c, w_idx + 1)) { return true; }
if (runner(r, c - 1, w_idx + 1)) { return true; }
if (runner(r, c + 1, w_idx + 1)) { return true; }
path_indices.erase(flat_idx);
return false;
};
// Loop over starting positions
for (int i = 0; i < ROWS; ++i) {
for (int j = 0; j < COLS; ++j) {
if (board[i][j] != word[0]) {
continue;
}
// Found the start of the word at (i,j)
// Perform a walk
if (runner(i, j, 0)) {
return true;
}
}
}
return false;
}
};