vector<string> findWords(vector<vector<char>>& board, vector<string>& words) {
int rows = board.size(), cols = board[0].size();
string word;
function<bool(int, int, int)> dfs = [&](int r, int c, int k) -> bool {
if (k == (int)word.size()) return true;
if (r < 0 || c < 0 || r >= rows || c >= cols) return false;
if (board[r][c] != word[k]) return false;
char saved = board[r][c];
board[r][c] = '#';
bool found = dfs(r + 1, c, k + 1) || dfs(r - 1, c, k + 1) || dfs(r, c + 1, k + 1) || dfs(r, c - 1, k + 1);
board[r][c] = saved;
return found;
};
auto exists = [&]() -> bool {
for (int r = 0; r < rows; r++) {
for (int c = 0; c < cols; c++) {
if (dfs(r, c, 0)) return true;
}
}
return false;
};
vector<string> result;
for (const string& w : words) {
word = w;
if (exists()) result.push_back(w);
}
return result;
}
public List<String> findWords(char[][] board, String[] words) {
int rows = board.length, cols = board[0].length;
List<String> result = new ArrayList<>();
for (String word : words) {
if (exists(board, word)) result.add(word);
}
return result;
}
private boolean exists(char[][] board, String word) {
int rows = board.length, cols = board[0].length;
for (int r = 0; r < rows; r++) {
for (int c = 0; c < cols; c++) {
if (dfs(board, word, r, c, 0)) return true;
}
}
return false;
}
private boolean dfs(char[][] board, String word, int r, int c, int k) {
if (k == word.length()) return true;
if (r < 0 || c < 0 || r >= board.length || c >= board[0].length) return false;
if (board[r][c] != word.charAt(k)) return false;
char saved = board[r][c];
board[r][c] = '#';
boolean found = dfs(board, word, r + 1, c, k + 1) || dfs(board, word, r - 1, c, k + 1) || dfs(board, word, r, c + 1, k + 1) || dfs(board, word, r, c - 1, k + 1);
board[r][c] = saved;
return found;
}
def find_words(board, words):
rows, cols = len(board), len(board[0])
def exists(word):
def dfs(r, c, k):
if k == len(word): return True
if r < 0 or c < 0 or r >= rows or c >= cols: return False
if board[r][c] != word[k]: return False
saved = board[r][c]
board[r][c] = '#'
found = dfs(r + 1, c, k + 1) or dfs(r - 1, c, k + 1) or dfs(r, c + 1, k + 1) or dfs(r, c - 1, k + 1)
board[r][c] = saved
return found
for r in range(rows):
for c in range(cols):
if dfs(r, c, 0): return True
return False
result = []
for word in words:
if exists(word): result.append(word)
return result
function findWords(board: string[][], words: string[]): string[] {
const rows = board.length, cols = board[0].length;
const exists = (word: string): boolean => {
const dfs = (r: number, c: number, k: number): boolean => {
if (k === word.length) return true;
if (r < 0 || c < 0 || r >= rows || c >= cols) return false;
if (board[r][c] !== word[k]) return false;
const saved = board[r][c];
board[r][c] = '#';
const found = dfs(r + 1, c, k + 1) || dfs(r - 1, c, k + 1) || dfs(r, c + 1, k + 1) || dfs(r, c - 1, k + 1);
board[r][c] = saved;
return found;
};
for (let r = 0; r < rows; r++) {
for (let c = 0; c < cols; c++) {
if (dfs(r, c, 0)) return true;
}
}
return false;
};
const result: string[] = [];
for (const word of words) {
if (exists(word)) result.push(word);
}
return result;
}
vector<string> findWords(vector<vector<char>>& board, vector<string>& words) {
unordered_set<string> wordSet(words.begin(), words.end());
unordered_set<string> prefixes;
for (const string& w : words) {
for (int i = 1; i <= (int)w.size(); i++) prefixes.insert(w.substr(0, i));
}
int rows = board.size(), cols = board[0].size();
set<string> found;
function<void(int, int, string)> dfs = [&](int r, int c, string path) {
if (r < 0 || c < 0 || r >= rows || c >= cols) return;
char ch = board[r][c];
if (ch == '#') return;
string next = path + ch;
if (!prefixes.count(next)) return;
if (wordSet.count(next)) found.insert(next);
board[r][c] = '#';
dfs(r + 1, c, next);
dfs(r - 1, c, next);
dfs(r, c + 1, next);
dfs(r, c - 1, next);
board[r][c] = ch;
};
for (int r = 0; r < rows; r++) {
for (int c = 0; c < cols; c++) dfs(r, c, "");
}
return vector<string>(found.begin(), found.end());
}
public List<String> findWords(char[][] board, String[] words) {
Set<String> wordSet = new HashSet<>(Arrays.asList(words));
Set<String> prefixes = new HashSet<>();
for (String w : words) {
for (int i = 1; i <= w.length(); i++) prefixes.add(w.substring(0, i));
}
int rows = board.length, cols = board[0].length;
Set<String> found = new TreeSet<>();
for (int r = 0; r < rows; r++) {
for (int c = 0; c < cols; c++) dfs(board, r, c, "", wordSet, prefixes, found);
}
return new ArrayList<>(found);
}
private void dfs(char[][] board, int r, int c, String path, Set<String> wordSet, Set<String> prefixes, Set<String> found) {
if (r < 0 || c < 0 || r >= board.length || c >= board[0].length) return;
char ch = board[r][c];
if (ch == '#') return;
String next = path + ch;
if (!prefixes.contains(next)) return;
if (wordSet.contains(next)) found.add(next);
board[r][c] = '#';
dfs(board, r + 1, c, next, wordSet, prefixes, found);
dfs(board, r - 1, c, next, wordSet, prefixes, found);
dfs(board, r, c + 1, next, wordSet, prefixes, found);
dfs(board, r, c - 1, next, wordSet, prefixes, found);
board[r][c] = ch;
}
def find_words(board, words):
word_set = set(words)
prefixes = set()
for w in words:
for i in range(1, len(w) + 1): prefixes.add(w[:i])
rows, cols = len(board), len(board[0])
found = set()
def dfs(r, c, path):
if r < 0 or c < 0 or r >= rows or c >= cols: return
ch = board[r][c]
if ch == '#': return
nxt = path + ch
if nxt not in prefixes: return
if nxt in word_set: found.add(nxt)
board[r][c] = '#'
dfs(r + 1, c, nxt)
dfs(r - 1, c, nxt)
dfs(r, c + 1, nxt)
dfs(r, c - 1, nxt)
board[r][c] = ch
for r in range(rows):
for c in range(cols): dfs(r, c, '')
return list(found)
function findWords(board: string[][], words: string[]): string[] {
const wordSet = new Set(words);
const prefixes = new Set<string>();
for (const w of words) {
for (let i = 1; i <= w.length; i++) prefixes.add(w.slice(0, i));
}
const rows = board.length, cols = board[0].length;
const found = new Set<string>();
const dfs = (r: number, c: number, path: string): void => {
if (r < 0 || c < 0 || r >= rows || c >= cols) return;
const ch = board[r][c];
if (ch === '#') return;
const next = path + ch;
if (!prefixes.has(next)) return;
if (wordSet.has(next)) found.add(next);
board[r][c] = '#';
dfs(r + 1, c, next);
dfs(r - 1, c, next);
dfs(r, c + 1, next);
dfs(r, c - 1, next);
board[r][c] = ch;
};
for (let r = 0; r < rows; r++) {
for (let c = 0; c < cols; c++) dfs(r, c, '');
}
return [...found];
}
struct Node {
unordered_map<char, Node*> kids;
string word; bool has = false;
};
vector<string> findWords(vector<vector<char>>& board, vector<string>& words) {
Node* root = new Node();
for (const string& w : words) {
Node* node = root;
for (char ch : w) {
if (!node->kids.count(ch)) node->kids[ch] = new Node();
node = node->kids[ch];
}
node->word = w; node->has = true;
}
int rows = board.size(), cols = board[0].size();
vector<string> result;
function<void(int, int, Node*)> dfs = [&](int r, int c, Node* node) {
if (r < 0 || c < 0 || r >= rows || c >= cols) return;
char ch = board[r][c];
auto it = node->kids.find(ch);
if (ch == '#' || it == node->kids.end()) return;
Node* next = it->second;
if (next->has) {
result.push_back(next->word);
next->has = false;
}
board[r][c] = '#';
dfs(r + 1, c, next);
dfs(r - 1, c, next);
dfs(r, c + 1, next);
dfs(r, c - 1, next);
board[r][c] = ch;
};
for (int r = 0; r < rows; r++) {
for (int c = 0; c < cols; c++) dfs(r, c, root);
}
return result;
}
static class Node {
Map<Character, Node> kids = new HashMap<>();
String word = null;
}
public List<String> findWords(char[][] board, String[] words) {
Node root = new Node();
for (String w : words) {
Node node = root;
for (char ch : w.toCharArray()) {
if (!node.kids.containsKey(ch)) node.kids.put(ch, new Node());
node = node.kids.get(ch);
}
node.word = w;
}
List<String> result = new ArrayList<>();
for (int r = 0; r < board.length; r++) {
for (int c = 0; c < board[0].length; c++) dfs(board, r, c, root, result);
}
return result;
}
private void dfs(char[][] board, int r, int c, Node node, List<String> result) {
if (r < 0 || c < 0 || r >= board.length || c >= board[0].length) return;
char ch = board[r][c];
Node next = node.kids.get(ch);
if (ch == '#' || next == null) return;
if (next.word != null) {
result.add(next.word);
next.word = null;
}
board[r][c] = '#';
dfs(board, r + 1, c, next, result);
dfs(board, r - 1, c, next, result);
dfs(board, r, c + 1, next, result);
dfs(board, r, c - 1, next, result);
board[r][c] = ch;
}
class Node:
def __init__(self):
self.kids = {}
self.word = None
def find_words(board, words):
root = Node()
for w in words:
node = root
for ch in w:
if ch not in node.kids: node.kids[ch] = Node()
node = node.kids[ch]
node.word = w
rows, cols = len(board), len(board[0])
result = []
def dfs(r, c, node):
if r < 0 or c < 0 or r >= rows or c >= cols: return
ch = board[r][c]
nxt = node.kids.get(ch)
if ch == '#' or nxt is None: return
if nxt.word is not None:
result.append(nxt.word)
nxt.word = None
board[r][c] = '#'
dfs(r + 1, c, nxt)
dfs(r - 1, c, nxt)
dfs(r, c + 1, nxt)
dfs(r, c - 1, nxt)
board[r][c] = ch
for r in range(rows):
for c in range(cols): dfs(r, c, root)
return result
class Node {
kids = new Map<string, Node>();
word: string | null = null;
}
function findWords(board: string[][], words: string[]): string[] {
const root = new Node();
for (const w of words) {
let node = root;
for (const ch of w) {
if (!node.kids.has(ch)) node.kids.set(ch, new Node());
node = node.kids.get(ch)!;
}
node.word = w;
}
const rows = board.length, cols = board[0].length;
const result: string[] = [];
const dfs = (r: number, c: number, node: Node): void => {
if (r < 0 || c < 0 || r >= rows || c >= cols) return;
const ch = board[r][c];
const next = node.kids.get(ch);
if (ch === '#' || next === undefined) return;
if (next.word !== null) {
result.push(next.word);
next.word = null;
}
board[r][c] = '#';
dfs(r + 1, c, next);
dfs(r - 1, c, next);
dfs(r, c + 1, next);
dfs(r, c - 1, next);
board[r][c] = ch;
};
for (let r = 0; r < rows; r++) {
for (let c = 0; c < cols; c++) dfs(r, c, root);
}
return result;
}
struct Node {
unordered_map<char, Node*> kids;
string word; bool has = false;
};
vector<string> findWords(vector<vector<char>>& board, vector<string>& words) {
Node* root = new Node();
for (const string& w : words) {
Node* node = root;
for (char ch : w) {
if (!node->kids.count(ch)) node->kids[ch] = new Node();
node = node->kids[ch];
}
node->word = w; node->has = true;
}
int rows = board.size(), cols = board[0].size();
vector<string> result;
function<void(int, int, Node*)> dfs = [&](int r, int c, Node* parent) {
char ch = board[r][c];
auto it = parent->kids.find(ch);
if (it == parent->kids.end()) return;
Node* node = it->second;
if (node->has) {
result.push_back(node->word);
node->has = false;
}
board[r][c] = '#';
if (r > 0 && board[r - 1][c] != '#') dfs(r - 1, c, node);
if (c > 0 && board[r][c - 1] != '#') dfs(r, c - 1, node);
if (r + 1 < rows && board[r + 1][c] != '#') dfs(r + 1, c, node);
if (c + 1 < cols && board[r][c + 1] != '#') dfs(r, c + 1, node);
board[r][c] = ch;
if (node->kids.empty() && !node->has) parent->kids.erase(ch);
};
for (int r = 0; r < rows; r++) {
for (int c = 0; c < cols; c++) dfs(r, c, root);
}
return result;
}
static class Node {
Map<Character, Node> kids = new HashMap<>();
String word = null;
}
public List<String> findWords(char[][] board, String[] words) {
Node root = new Node();
for (String w : words) {
Node node = root;
for (char ch : w.toCharArray()) {
if (!node.kids.containsKey(ch)) node.kids.put(ch, new Node());
node = node.kids.get(ch);
}
node.word = w;
}
List<String> result = new ArrayList<>();
for (int r = 0; r < board.length; r++) {
for (int c = 0; c < board[0].length; c++) dfs(board, r, c, root, result);
}
return result;
}
private void dfs(char[][] board, int r, int c, Node parent, List<String> result) {
char ch = board[r][c];
Node node = parent.kids.get(ch);
if (node == null) return;
if (node.word != null) {
result.add(node.word);
node.word = null;
}
board[r][c] = '#';
if (r > 0 && board[r - 1][c] != '#') dfs(board, r - 1, c, node, result);
if (c > 0 && board[r][c - 1] != '#') dfs(board, r, c - 1, node, result);
if (r + 1 < board.length && board[r + 1][c] != '#') dfs(board, r + 1, c, node, result);
if (c + 1 < board[0].length && board[r][c + 1] != '#') dfs(board, r, c + 1, node, result);
board[r][c] = ch;
if (node.kids.isEmpty() && node.word == null) parent.kids.remove(ch);
}
class Node:
def __init__(self):
self.kids = {}
self.word = None
def find_words(board, words):
root = Node()
for w in words:
node = root
for ch in w:
if ch not in node.kids: node.kids[ch] = Node()
node = node.kids[ch]
node.word = w
rows, cols = len(board), len(board[0])
result = []
def dfs(r, c, parent):
ch = board[r][c]
node = parent.kids.get(ch)
if node is None: return
if node.word is not None:
result.append(node.word)
node.word = None
board[r][c] = '#'
if r > 0 and board[r - 1][c] != '#': dfs(r - 1, c, node)
if c > 0 and board[r][c - 1] != '#': dfs(r, c - 1, node)
if r + 1 < rows and board[r + 1][c] != '#': dfs(r + 1, c, node)
if c + 1 < cols and board[r][c + 1] != '#': dfs(r, c + 1, node)
board[r][c] = ch
if not node.kids and node.word is None: del parent.kids[ch]
for r in range(rows):
for c in range(cols): dfs(r, c, root)
return result
class Node {
kids = new Map<string, Node>();
word: string | null = null;
}
function findWords(board: string[][], words: string[]): string[] {
const root = new Node();
for (const w of words) {
let node = root;
for (const ch of w) {
if (!node.kids.has(ch)) node.kids.set(ch, new Node());
node = node.kids.get(ch)!;
}
node.word = w;
}
const rows = board.length, cols = board[0].length;
const result: string[] = [];
const dfs = (r: number, c: number, parent: Node): void => {
const ch = board[r][c];
const node = parent.kids.get(ch);
if (node === undefined) return;
if (node.word !== null) {
result.push(node.word);
node.word = null;
}
board[r][c] = '#';
if (r > 0 && board[r - 1][c] !== '#') dfs(r - 1, c, node);
if (c > 0 && board[r][c - 1] !== '#') dfs(r, c - 1, node);
if (r + 1 < rows && board[r + 1][c] !== '#') dfs(r + 1, c, node);
if (c + 1 < cols && board[r][c + 1] !== '#') dfs(r, c + 1, node);
board[r][c] = ch;
if (node.kids.size === 0 && node.word === null) parent.kids.delete(ch);
};
for (let r = 0; r < rows; r++) {
for (let c = 0; c < cols; c++) dfs(r, c, root);
}
return result;
}