Skip to content

Commit 8b68505

Browse files
committed
word search ii solution
1 parent ac79eca commit 8b68505

File tree

1 file changed

+176
-0
lines changed

1 file changed

+176
-0
lines changed

word-search-ii/hyer0705.ts

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
// 84ms
2+
class TrieNode {
3+
children: Map<string, TrieNode>;
4+
isEndOf: boolean;
5+
word: string | null;
6+
7+
constructor() {
8+
this.children = new Map();
9+
this.word = null;
10+
}
11+
}
12+
class Trie {
13+
root: TrieNode;
14+
15+
constructor() {
16+
this.root = new TrieNode();
17+
}
18+
19+
insert(word: string) {
20+
let current = this.root;
21+
22+
for (const char of word) {
23+
if (!current.children.has(char)) {
24+
current.children.set(char, new TrieNode());
25+
}
26+
current = current.children.get(char);
27+
}
28+
29+
current.word = word;
30+
}
31+
}
32+
33+
function findWords(board: string[][], words: string[]): string[] {
34+
const m = board.length;
35+
const n = board[0].length;
36+
37+
const dictionary = new Trie();
38+
for (const word of words) {
39+
dictionary.insert(word);
40+
}
41+
42+
const results: string[] = [];
43+
44+
const dfs = (row: number, col: number, trieNode: TrieNode) => {
45+
if (trieNode.word !== null) {
46+
results.push(trieNode.word);
47+
trieNode.word = null;
48+
}
49+
50+
const directions = [
51+
[-1, 0],
52+
[1, 0],
53+
[0, -1],
54+
[0, 1],
55+
];
56+
57+
for (const [dr, dc] of directions) {
58+
const [nr, nc] = [row + dr, col + dc];
59+
60+
if (nr >= 0 && nr < m && nc >= 0 && nc < n) {
61+
if (trieNode.children.has(board[nr][nc])) {
62+
const char = board[nr][nc];
63+
const childNode = trieNode.children.get(char);
64+
65+
if (board[nr][nc] !== "#") {
66+
board[nr][nc] = "#";
67+
dfs(nr, nc, trieNode.children.get(char));
68+
board[nr][nc] = char;
69+
}
70+
71+
if (childNode.children.size === 0 && childNode.word === null) {
72+
trieNode.children.delete(char);
73+
}
74+
}
75+
}
76+
}
77+
};
78+
79+
for (let i = 0; i < m; i++) {
80+
for (let j = 0; j < n; j++) {
81+
const firstChar = board[i][j];
82+
if (dictionary.root.children.has(firstChar)) {
83+
board[i][j] = "#";
84+
dfs(i, j, dictionary.root.children.get(firstChar));
85+
board[i][j] = firstChar;
86+
}
87+
}
88+
}
89+
90+
return results;
91+
}
92+
93+
// 2312ms
94+
class TrieNode {
95+
children: Map<string, TrieNode>;
96+
word: string | null;
97+
98+
constructor() {
99+
this.children = new Map();
100+
this.word = null;
101+
}
102+
}
103+
class Trie {
104+
root: TrieNode;
105+
106+
constructor() {
107+
this.root = new TrieNode();
108+
}
109+
110+
insert(word: string) {
111+
let current = this.root;
112+
113+
for (const char of word) {
114+
if (!current.children.has(char)) {
115+
current.children.set(char, new TrieNode());
116+
}
117+
current = current.children.get(char)!;
118+
}
119+
120+
current.word = word;
121+
}
122+
}
123+
124+
function findWords(board: string[][], words: string[]): string[] {
125+
const m = board.length;
126+
const n = board[0].length;
127+
128+
const dictionary = new Trie();
129+
for (const word of words) {
130+
dictionary.insert(word);
131+
}
132+
133+
const results: string[] = [];
134+
135+
const dfs = (row: number, col: number, trieNode: TrieNode, path: string) => {
136+
if (trieNode.word === path) {
137+
results.push(path);
138+
trieNode.word = null;
139+
}
140+
141+
const directions = [
142+
[-1, 0],
143+
[1, 0],
144+
[0, -1],
145+
[0, 1],
146+
];
147+
148+
for (const [dr, dc] of directions) {
149+
const [nr, nc] = [row + dr, col + dc];
150+
151+
if (nr >= 0 && nr < m && nc >= 0 && nc < n) {
152+
if (trieNode.children.has(board[nr][nc])) {
153+
if (!isVisited.has(`${nr},${nc}`)) {
154+
isVisited.add(`${nr},${nc}`);
155+
dfs(nr, nc, trieNode.children.get(board[nr][nc])!, path + board[nr][nc]);
156+
isVisited.delete(`${nr},${nc}`);
157+
}
158+
}
159+
}
160+
}
161+
};
162+
163+
const isVisited = new Set<string>(); // 'r,c'
164+
for (let i = 0; i < m; i++) {
165+
for (let j = 0; j < n; j++) {
166+
const firstChar = board[i][j];
167+
if (dictionary.root.children.has(firstChar)) {
168+
isVisited.add(`${i},${j}`);
169+
dfs(i, j, dictionary.root.children.get(firstChar)!, firstChar);
170+
isVisited.delete(`${i},${j}`);
171+
}
172+
}
173+
}
174+
175+
return results;
176+
}

0 commit comments

Comments
 (0)