Skip to content

Commit c250f4b

Browse files
committed
feat: add solutions to lc problem: No.0079
No.0079.Word Search
1 parent 2a39d36 commit c250f4b

File tree

8 files changed

+420
-426
lines changed

8 files changed

+420
-426
lines changed

solution/0000-0099/0079.Word Search/README.md

+159-153
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,19 @@
5353

5454
<!-- 这里可写通用的实现逻辑 -->
5555

56-
回溯(深度优先搜索 DFS )实现。
56+
**方法一:DFS(回溯)**
57+
58+
我们可以枚举网格的每一个位置 $(i, j)$ 作为搜索的起点,然后从起点开始进行深度优先搜索,如果可以搜索到单词的末尾,就说明单词存在,否则说明单词不存在。
59+
60+
因此,我们设计一个函数 $dfs(i, j, k)$,表示从网格的 $(i, j)$ 位置出发,且从单词的第 $k$ 个字符开始搜索,是否能够搜索成功。函数 $dfs(i, j, k)$ 的执行步骤如下:
61+
62+
- 如果 $k = |word|-1$,说明已经搜索到单词的最后一个字符,此时只需要判断网格 $(i, j)$ 位置的字符是否等于 $word[k]$,如果相等则说明单词存在,否则说明单词不存在。无论单词是否存在,都无需继续往下搜索,因此直接返回结果。
63+
- 否则,如果 $word[k]$ 字符不等于网格 $(i, j)$ 位置的字符,说明本次搜索失败,直接返回 `false`
64+
- 否则,我们将网格 $(i, j)$ 位置的字符暂存于 $c$ 中,然后将此位置的字符修改为一个特殊字符 `'0'`,代表此位置的字符已经被使用过,防止之后搜索时重复使用。然后我们从 $(i, j)$ 位置的上、下、左、右四个方向分别出发,去搜索网格中第 $k+1$ 个字符,如果四个方向有任何一个方向搜索成功,就说明搜索成功,否则说明搜索失败,此时我们需要还原网格 $(i, j)$ 位置的字符,即把 $c$ 放回网格 $(i, j)$ 位置(回溯)。
65+
66+
在主函数中,我们枚举网格中的每一个位置 $(i, j)$ 作为起点,如果调用 $dfs(i, j, 0)$ 返回 `true`,就说明单词存在,否则说明单词不存在,返回 `false`
67+
68+
时间复杂度 $O(m \times n \times 3^k)$,空间复杂度 $O(\min(m \times n, k))$。其中 $m$ 和 $n$ 分别是网格的行数和列数;而 $k$ 是字符串 $word$ 的长度。
5769

5870
<!-- tabs:start -->
5971

@@ -64,25 +76,19 @@
6476
```python
6577
class Solution:
6678
def exist(self, board: List[List[str]], word: str) -> bool:
67-
def dfs(i, j, cur):
68-
if cur == len(word):
69-
return True
70-
if (
71-
i < 0
72-
or i >= m
73-
or j < 0
74-
or j >= n
75-
or board[i][j] == '0'
76-
or word[cur] != board[i][j]
77-
):
79+
def dfs(i: int, j: int, k: int) -> bool:
80+
if k == len(word) - 1:
81+
return board[i][j] == word[k]
82+
if board[i][j] != word[k]:
7883
return False
79-
t = board[i][j]
80-
board[i][j] = '0'
81-
for a, b in [[0, 1], [0, -1], [-1, 0], [1, 0]]:
84+
c = board[i][j]
85+
board[i][j] = "0"
86+
for a, b in pairwise((-1, 0, 1, 0, -1)):
8287
x, y = i + a, j + b
83-
if dfs(x, y, cur + 1):
88+
ok = 0 <= x < m and 0 <= y < n and board[x][y] != "0"
89+
if ok and dfs(x, y, k + 1):
8490
return True
85-
board[i][j] = t
91+
board[i][j] = c
8692
return False
8793

8894
m, n = len(board), len(board[0])
@@ -95,94 +101,45 @@ class Solution:
95101

96102
```java
97103
class Solution {
104+
private int m;
105+
private int n;
106+
private String word;
107+
private char[][] board;
108+
98109
public boolean exist(char[][] board, String word) {
99-
int m = board.length;
100-
int n = board[0].length;
110+
m = board.length;
111+
n = board[0].length;
112+
this.word = word;
113+
this.board = board;
101114
for (int i = 0; i < m; ++i) {
102115
for (int j = 0; j < n; ++j) {
103-
if (dfs(i, j, 0, m, n, board, word)) {
116+
if (dfs(i, j, 0)) {
104117
return true;
105118
}
106119
}
107120
}
108121
return false;
109122
}
110123

111-
private boolean dfs(int i, int j, int cur, int m, int n, char[][] board, String word) {
112-
if (cur == word.length()) {
113-
return true;
124+
private boolean dfs(int i, int j, int k) {
125+
if (k == word.length() - 1) {
126+
return board[i][j] == word.charAt(k);
114127
}
115-
if (i < 0 || i >= m || j < 0 || j >= n || board[i][j] != word.charAt(cur)) {
128+
if (board[i][j] != word.charAt(k)) {
116129
return false;
117130
}
118-
board[i][j] += 256;
131+
char c = board[i][j];
132+
board[i][j] = '0';
119133
int[] dirs = {-1, 0, 1, 0, -1};
120-
for (int k = 0; k < 4; ++k) {
121-
int x = i + dirs[k];
122-
int y = j + dirs[k + 1];
123-
if (dfs(x, y, cur + 1, m, n, board, word)) {
134+
for (int u = 0; u < 4; ++u) {
135+
int x = i + dirs[u], y = j + dirs[u + 1];
136+
if (x >= 0 && x < m && y >= 0 && y < n && board[x][y] != '0' && dfs(x, y, k + 1)) {
124137
return true;
125138
}
126139
}
127-
board[i][j] -= 256;
128-
return false;
129-
}
130-
}
131-
```
132-
133-
### **TypeScript**
134-
135-
```ts
136-
function exist(board: string[][], word: string): boolean {
137-
let m = board.length,
138-
n = board[0].length;
139-
let visited = Array.from({ length: m }, v => new Array(n).fill(false));
140-
for (let i = 0; i < m; ++i) {
141-
for (let j = 0; j < n; ++j) {
142-
if (dfs(board, word, i, j, 0, visited)) {
143-
return true;
144-
}
145-
}
146-
}
147-
return false;
148-
}
149-
150-
function dfs(
151-
board: string[][],
152-
word: string,
153-
i: number,
154-
j: number,
155-
depth: number,
156-
visited: boolean[][],
157-
): boolean {
158-
let m = board.length,
159-
n = board[0].length;
160-
if (i < 0 || i > m - 1 || j < 0 || j > n - 1 || visited[i][j]) {
140+
board[i][j] = c;
161141
return false;
162142
}
163-
if (board[i][j] != word.charAt(depth)) {
164-
return false;
165-
}
166-
167-
if (depth == word.length - 1) {
168-
return true;
169-
}
170-
171-
visited[i][j] = true;
172-
++depth;
173-
let res = false;
174-
for (let [dx, dy] of [
175-
[0, 1],
176-
[0, -1],
177-
[1, 0],
178-
[-1, 0],
179-
]) {
180-
let x = i + dx,
181-
y = j + dy;
182-
res = res || dfs(board, word, x, y, depth, visited);
183-
}
184-
visited[i][j] = false;
185-
return res;
186143
}
187144
```
188145

@@ -193,94 +150,60 @@ class Solution {
193150
public:
194151
bool exist(vector<vector<char>>& board, string word) {
195152
int m = board.size(), n = board[0].size();
196-
for (int i = 0; i < m; ++i)
197-
for (int j = 0; j < n; ++j)
198-
if (dfs(i, j, 0, m, n, board, word))
153+
int dirs[5] = {-1, 0, 1, 0, -1};
154+
function<bool(int, int, int)> dfs = [&](int i, int j, int k) -> bool {
155+
if (k == word.size() - 1) {
156+
return board[i][j] == word[k];
157+
}
158+
if (board[i][j] != word[k]) {
159+
return false;
160+
}
161+
char c = board[i][j];
162+
board[i][j] = '0';
163+
for (int u = 0; u < 4; ++u) {
164+
int x = i + dirs[u], y = j + dirs[u + 1];
165+
if (x >= 0 && x < m && y >= 0 && y < n && board[x][y] != '0' && dfs(x, y, k + 1)) {
199166
return true;
200-
return false;
201-
}
202-
203-
bool dfs(int i, int j, int cur, int m, int n, vector<vector<char>>& board, string& word) {
204-
if (cur == word.size()) return true;
205-
if (i < 0 || i >= m || j < 0 || j >= n || board[i][j] != word[cur]) return false;
206-
char t = board[i][j];
207-
board[i][j] = '0';
208-
vector<int> dirs = {-1, 0, 1, 0, -1};
209-
for (int k = 0; k < 4; ++k) {
210-
int x = i + dirs[k], y = j + dirs[k + 1];
211-
if (dfs(x, y, cur + 1, m, n, board, word)) return true;
212-
}
213-
board[i][j] = t;
214-
return false;
215-
}
216-
};
217-
```
218-
219-
### **C#**
220-
221-
```cs
222-
public class Solution {
223-
public bool Exist(char[][] board, string word) {
224-
var lenI = board.Length;
225-
var lenJ = lenI == 0 ? 0 : board[0].Length;
226-
var visited = new bool[lenI, lenJ];
227-
for (var i = 0; i < lenI; ++i)
228-
{
229-
for (var j = 0; j < lenJ; ++j)
230-
{
231-
if (Search(board, visited, word, lenI, lenJ, i, j, 0))
232-
{
167+
}
168+
}
169+
board[i][j] = c;
170+
return false;
171+
};
172+
for (int i = 0; i < m; ++i) {
173+
for (int j = 0; j < n; ++j) {
174+
if (dfs(i, j, 0)) {
233175
return true;
234176
}
235177
}
236178
}
237179
return false;
238180
}
239-
240-
private int[,] paths = new int[4,2] { { -1, 0 }, { 1, 0 }, { 0, -1 }, { 0, 1 } };
241-
242-
private bool Search(char[][] board, bool[,] visited, string word, int lenI, int lenJ, int i, int j, int p)
243-
{
244-
if (p == word.Length)
245-
{
246-
return true;
247-
}
248-
if (i < 0 || i >= lenI || j < 0 || j >= lenJ) return false;
249-
if (visited[i, j] || word[p] != board[i][j]) return false;
250-
visited[i, j] = true;
251-
for (var k = 0; k < 4; ++k)
252-
{
253-
if (Search(board, visited, word, lenI, lenJ, i + paths[k, 0], j + paths[k, 1], p + 1)) return true;
254-
}
255-
visited[i, j] = false;
256-
return false;
257-
}
258-
}
181+
};
259182
```
260183
261184
### **Go**
262185
263186
```go
264187
func exist(board [][]byte, word string) bool {
265188
m, n := len(board), len(board[0])
266-
var dfs func(i, j, cur int) bool
267-
dfs = func(i, j, cur int) bool {
268-
if cur == len(word) {
269-
return true
189+
var dfs func(int, int, int) bool
190+
dfs = func(i, j, k int) bool {
191+
if k == len(word)-1 {
192+
return board[i][j] == word[k]
270193
}
271-
if i < 0 || i >= m || j < 0 || j >= n || board[i][j] != word[cur] {
194+
if board[i][j] != word[k] {
272195
return false
273196
}
274-
t := board[i][j]
197+
dirs := [5]int{-1, 0, 1, 0, -1}
198+
c := board[i][j]
275199
board[i][j] = '0'
276-
dirs := []int{-1, 0, 1, 0, -1}
277-
for k := 0; k < 4; k++ {
278-
x, y := i+dirs[k], j+dirs[k+1]
279-
if dfs(x, y, cur+1) {
200+
for u := 0; u < 4; u++ {
201+
x, y := i+dirs[u], j+dirs[u+1]
202+
if x >= 0 && x < m && y >= 0 && y < n && board[x][y] != '0' && dfs(x, y, k+1) {
280203
return true
281204
}
282205
}
283-
board[i][j] = t
206+
board[i][j] = c
284207
return false
285208
}
286209
for i := 0; i < m; i++ {
@@ -294,6 +217,89 @@ func exist(board [][]byte, word string) bool {
294217
}
295218
```
296219

220+
### **TypeScript**
221+
222+
```ts
223+
function exist(board: string[][], word: string): boolean {
224+
const [m, n] = [board.length, board[0].length];
225+
const dirs = [-1, 0, 1, 0, -1];
226+
const dfs = (i: number, j: number, k: number): boolean => {
227+
if (k === word.length - 1) {
228+
return board[i][j] === word[k];
229+
}
230+
if (board[i][j] !== word[k]) {
231+
return false;
232+
}
233+
const c = board[i][j];
234+
board[i][j] = '0';
235+
for (let u = 0; u < 4; ++u) {
236+
const [x, y] = [i + dirs[u], j + dirs[u + 1]];
237+
const ok = x >= 0 && x < m && y >= 0 && y < n;
238+
if (ok && board[x][y] !== '0' && dfs(x, y, k + 1)) {
239+
return true;
240+
}
241+
}
242+
board[i][j] = c;
243+
return false;
244+
};
245+
for (let i = 0; i < m; ++i) {
246+
for (let j = 0; j < n; ++j) {
247+
if (dfs(i, j, 0)) {
248+
return true;
249+
}
250+
}
251+
}
252+
return false;
253+
}
254+
```
255+
256+
### **C#**
257+
258+
```cs
259+
public class Solution {
260+
private int m;
261+
private int n;
262+
private char[][] board;
263+
private string word;
264+
265+
public bool Exist(char[][] board, string word) {
266+
m = board.Length;
267+
n = board[0].Length;
268+
this.board = board;
269+
this.word = word;
270+
for (int i = 0; i < m; ++i) {
271+
for (int j = 0; j < n; ++j) {
272+
if (dfs(i, j, 0)) {
273+
return true;
274+
}
275+
}
276+
}
277+
return false;
278+
}
279+
280+
private bool dfs(int i, int j, int k) {
281+
if (k == word.Length - 1) {
282+
return board[i][j] == word[k];
283+
}
284+
if (board[i][j] != word[k]) {
285+
return false;
286+
}
287+
char c = board[i][j];
288+
board[i][j] = '0';
289+
int[] dirs = { -1, 0, 1, 0, -1 };
290+
for (int u = 0; u < 4; ++u) {
291+
int x = i + dirs[u];
292+
int y = j + dirs[u + 1];
293+
if (x >= 0 && x < m && y >= 0 && y < n && board[x][y] != '0' && dfs(x, y, k + 1)) {
294+
return true;
295+
}
296+
}
297+
board[i][j] = c;
298+
return false;
299+
}
300+
}
301+
```
302+
297303
### **Rust**
298304

299305
```rust

0 commit comments

Comments
 (0)