use std::collections::HashSet;
struct Solution;
impl Solution {
fn exist(board: Vec<Vec<char>>, word: String) -> bool {
let rows = board.len();
if rows == 0 { return false; }
let cols = board[0].len();
if cols == 0 { return false; }
let word_chars: Vec<char> = word.chars().collect();
fn backtrack(
board: &Vec<Vec<char>>,
word: &Vec<char>,
index: usize,
row: usize,
col: usize,
visited: &mut HashSet<(usize, usize)>,
) -> bool {
if index == word.len() {
return true; // All letters matched
}
if row >= board.len() || col >= board[0].len() {
return false; // Out of bounds
}
if board[row][col] != word[index] {
return false; // Letter does not match
}
if visited.contains(&(row, col)) {
return false; // Already visited this cell
}
visited.insert((row, col));
// Explore neighbors: up, down, left, right
let directions = [(-1, 0), (1, 0), (0, -1), (0, 1)];
for (dr, dc) in directions.iter() {
let new_row = row as isize + dr;
let new_col = col as isize + dc;
if new_row >= 0
&& new_row < board.len() as isize
&& new_col >= 0
&& new_col < board[0].len() as isize
{
if backtrack(
board,
word,
index + 1,
new_row as usize,
new_col as usize,
visited,
) {
return true; // Found path
}
}
}
visited.remove(&(row, col)); // Backtrack
false
}
for r in 0..rows {
for c in 0..cols {
let mut visited = HashSet::new();
if backtrack(&board, &word_chars, 0, r, c, &mut visited) {
return true;
}
}
}
false
}
}
fn main() {
let board = vec![
vec!['A', 'B', 'C', 'E'],
vec!['S', 'F', 'C', 'S'],
vec!['A', 'D', 'E', 'E'],
];
let word = String::from("SEE");
let result = Solution::exist(board, word);
println!("{}", result);
}if index == word.len() { return true; }
All letters matched, successful end condition
if row >= board.len() || col >= board[0].len() { return false; }
Check out of bounds to avoid invalid access
if board[row][col] != word[index] { return false; }
Current cell letter must match current word letter
if visited.contains(&(row, col)) { return false; }
Avoid revisiting same cell in current path
visited.insert((row, col));
Mark current cell as visited before exploring neighbors
for (dr, dc) in directions.iter() { ... backtrack(...) }
Explore all four directions recursively for next letter
visited.remove(&(row, col));
Backtrack by unmarking cell if path fails
for r in 0..rows { for c in 0..cols { ... backtrack(...) } }
Try starting backtracking from every cell in the grid